继承、派生,组合,接口归一化设计,抽象类
day28
继承
参阅博客:http://www.cnblogs.com/linhaifeng/articles/7340153.html
什么是继承,从语法角度:
class A: # 父类A pass class B: # 父类B pass class C(A): # 子类C,继承父类A pass class D(A, B): # 子类D,继承父类A和B,python可以同时继承多个父类 pass
继承是一种创建新的类的方式。
继承是一种“是”的关系:
人类、猪类、狗类都是继承动物类,因因而他们都是动物。
如何寻找继承关系:
为什么要用继承:
解决代码重用问题。
解决的是:什么是什么的问题
派生
子类继承了父类的属性,然后衍生出自己的属性,如果子类衍生出的新的属性与父类的某个属性名字相同,那么再调用子类的这个属性,就以子类自己这里的为准了。
在子类中重用父类的函数:父类名.父类的函数(函数)
class People:
def __init__(self, name, sex, age):
self.name = name
self.sex = self
self.age = age
def walk(self):
print("%s is walking.." % (self.name))
class Chinese(People):
country = "China"
def __init__(self, name, sex, age, language="Chinese"): # 派生出一个子类自己的方法,比父类多了language参数
# self.name=name
# self.sex=sex
# self.age=age
People.__init__(self, name, sex, age) # 重用父类的方法,上面三行代码即可省略
self.langueage = language
class North_korean(People):
country = "Korea"
c = Chinese("alex", "male", 18)
print(c.name, c.country, c.langueage)
c.walk()
运行结果:
alex China Chinese alex is walking..
组合
参阅博客:http://www.cnblogs.com/linhaifeng/articles/7340153.html#_label5
组合对比继承来说,也是用来重用代码,但是组合描述的是一种“有”的关系。
如:
老师有课程
学生有成绩
学校有老师
学校有学生
class Teacher:
def __init__(self, name, sex, course):
self.name = name
self.sex = sex
self.course = course
class Student:
def __init__(self, name, sex, course):
self.name = name
self.sex = sex
self.course = course
class Course:
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
python_obj = Course("python", "15800", "7m")
t1 = Teacher("egon", "male", python_obj)
s1 = Student("alex", "male", python_obj)
print(t1.course.name)
print(s1.course.name)
运行结果:
python python
接口与归一化设计
参阅博客:http://www.cnblogs.com/linhaifeng/articles/7340153.html#_label6
Java有interface来定义接口,但是Python没有接口这么一说,但是可以通过继承来模拟。
归一化设计:如人和猪都能吃能跑,对于调用者而言,我只需要调用吃或跑的方法就行,至于人和猪各自是怎么跑的便不用管。
# 接口与归一化设计
class Animal:
def eat(self):
pass
def run(self):
pass
class Poeple(Animal):
def eat(self):
print("人在吃")
def run(self):
print("人在跑")
class Pig(Animal):
def eat(self):
print("猪在吃")
def run(self):
print("猪在跑")
poe = Poeple()
poe.eat()
pig = Pig()
pig.eat()
运行结果:
人在吃
猪在吃
上面的例子如果子类没有对接口(父类)方法进行实现也不会报错,没有实现便会到父类去找,但是接口应该是只起定义作用,最好是子类各自进行实现,如何限制子类必须进行实现呢,如下:
# 接口与归一化设计
class Animal:
def eat(self):
raise AttributeError("子类必须要实现这个方法")
def run(self):
raise AttributeError("子类必须要实现这个方法") # 当子类没有进行方法实现的时候抛出异常信息
class Poeple(Animal):
def eat(self):
print("人在吃")
# def run(self):
# print("人在跑")
poe = Poeple()
poe.run() # 子类未对run()方法进行实现,会报错
运行结果:
Traceback (most recent call last):
File "D:/PycharmProjects/python_fullstack_s4/day28/接口与归一化设计.py", line 19, in <module>
poe.run() # 子类未对run()方法进行实现,会报错
File "D:/PycharmProjects/python_fullstack_s4/day28/接口与归一化设计.py", line 7, in run
raise AttributeError("子类必须要实现这个方法")
AttributeError: 子类必须要实现这个方法
用raise的方式比较low,还可以引入抽象类的方式进行修改,如下:
导入abc模块进行实现:
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def eat(self):
pass
@abc.abstractmethod
def run(self):
pass
class Poeple(Animal):
def eat(self):
print("人在吃")
# def run(self):
# print("人在跑")
poe = Poeple()
poe.run() # 子类未对run()方法进行实现,会报错
运行结果:
Traceback (most recent call last): File "D:/PycharmProjects/python_fullstack_s4/day28/抽象类.py", line 22, in <module> poe = Poeple() TypeError: Can't instantiate abstract class Poeple with abstract methods run
抽象类
如上例子。
另参阅博客:http://www.cnblogs.com/linhaifeng/articles/7340153.html#_label7

共有 0 条评论