一、什么是继承:
继承是一种创建新的类的方式,新建的类可以继承一个或过个父类,原始类成为基类或超类,新建的类则称为派生类
或子类。
其中,继承又分为:单继承和多继承。
class parent_class1: #定义父类(基类或超类)
pass
class parent_class2: #定义父类(基类或超类)
pass
class subclass1(parent_class1): #单继承,父类(基类或超类)是:parent_class1,
pass # 子类(派生类)是:subclass。
class subclass2(parent_class1,parent_class2): #支持多继承,括号里的父类用逗号隔开
pass
注意:圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在
子类中未找到时,从左到右查找父类中是否包含方法。
查看继承:
print(subclass1.__bases__) print(subclass2.__bases__) ------------------输出结果-------------------------- (<class '__main__.parent_class1'>,) (<class '__main__.parent_class1'>, <class '__main__.parent_class2'>)
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方
法(如__str__)的实现。
print(parent_class1.__bases__) print(parent_class2.__bases__) --------------输出结果----------------- (<class 'object'>,) #默认继承的父类 (<class 'object'>,) #默认继承的父类
二、继承与抽象(先抽象后继承)
抽象:抽取类似的或者比较像的部分,就是找出共同点。
抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到我们想要的类
抽象分为两步:
1、先将奔驰和宝马这两对象比较像的部分抽取成类;
2、再将轿车、货车、摩托车这三个类,比较像的部分抽取成父类。
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象
的结构。
三、继承与重用性
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同
时,我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用。
class motor_vehicle: #父类:机动车
tag = "fuel oil" #共有的特征都必须烧燃油
def __init__(self,brand,motorcycle_type,displacement):
self.brand = brand #车辆品牌
self.motorcycle_type = motorcycle_type #车辆类型
self.displacement = displacement #车辆排量
def advance(self): #都有前进的技能
print("%s,出发了!"%self.brand)
def stop(self,other): #都有刹车技能
print("%s,遇到开 %s 的帅哥减速了!"%(self.brand,other.brand))
class saloon(motor_vehicle): #轿车类继承父类(机动车)
pass
class motorcycle(motor_vehicle): #摩托车类继承父类(机动车)
pass
s1 = saloon("奔驰","saloon",600) #实例化对象s1
m1 = motorcycle("春风","motorcycle",650) #实例化对象m1
print(s1.displacement) #查看s1的排量
print(m1.brand) #查看m1的品牌
s1.stop(m1) #对象调用对应的绑定方法。
-------------------输出结果---------------------------
600
春风
奔驰,遇到开 春风 的帅哥减速了!
提示:用已经有的类建立一个新的类,这样就重用了已经有的软件中的代码,大大增加了编程的工作量,这就是常说
的代码重用,不仅可以重用自己的类,也可以继承别人的,比如标准库,来定制新的数据类型,这样就是大大缩短了软件
开发周期,对大型软件开发来说,意义重大.
注意:像m1.brand之类的属性引用,会先从实例中找brand然后去类中找,然后再去父类中找...直到最顶级的父类。
当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新
定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
class motorcycle(motor_vehicle): #摩托车类继承父类(机动车)
def advance(self):#在自己这里定义新的advance,不再使用父类的advance,且不会影响父类
print("from motorcycle")
def fun(self): #定义新的功能
print("michael is a motorcycle trip")
---------------输出结果-------------------
from motorcycle
michael is a motorcycle trip
在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是
用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值了。
class motorcycle(motor_vehicle): #摩托车类继承父类(机动车)
def __init__(self,brand,motorcycle_type,displacement,owner):
motor_vehicle.__init__(self,brand,motorcycle_type,displacement)
self.owner = owner #增加新的属性
def advance(self):#在自己这里定义新的advance,不再使用父类的advance,且不会影响父类
print("from motorcycle")
def fun(self): #定义新的功能
print("%s is a motorcycle trip"%self.owner)
print("------下面是调用父类中的功能-------")
motor_vehicle.stop(m1,m1) #调用父类中的功能
m1 = motorcycle("春风","motorcycle",650,"michael") #实例化对象m1
print(m1.owner) #查看新增的属性春风机车的车主是谁
m1.advance() #调用m1的绑定方法
m1.fun() #调用m1的绑定方法,其中有调用父类中的功能
------------------------输出结果--------------------------
michael
from motorcycle
michael is a motorcycle trip
------下面是调用父类中的功能-------
春风,遇到开 春风 的帅哥减速了!
四、组合与重用性
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
比如咱们现在要去摩旅,得需要一些必要的装备吧,简单点,就先来一个导航仪(GPS)吧!
#定义装备类
class equipment: #摩旅需要的装备
def gps(self): #定义GPS这个技能
print("gps全程为您服务!")
#定义摩托车类
class motorcycle(motor_vehicle): #摩托车摩旅都需要装备,因而需要组合equipment类
def __init__(self,brand,motorcycle_type,displacement):
motor_vehicle.__init__(self,brand,motorcycle_type,displacement)
self.equipment = equipment() # 用equipment类产生一个装备,赋值给实例的equipment属性
def advance(self):#在自己这里定义新的advance,不再使用父类的advance,且不会影响父类
print("from motorcycle")
def fun(self): #定义新的功能
print("michael is a motorcycle trip")
m1 = motorcycle("春风","motorcycle",650) #实例化对象m1
m1.equipment.gps() #可以使用组合的类产生的对象所持有的方法
----------------输出结果------------------
gps全程为您服务!
注意:组合与继承都是有效地利用已有类的资源的重要方式,但是二者的概念和使用场景皆不同。
1、继承的方式
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如奔驰是轿车,货车车是机动车。当类之间有很
多相同的功能,提取这些共同的功能做成基类,用继承比较好。
比如摩托车是机动车:
class motor_vehicle: #父类:机动车
tag = "fuel oil" #共有的特征都必须烧燃油
def __init__(self,brand,motorcycle_type,displacement):
self.brand = brand #车辆品牌
self.motorcycle_type = motorcycle_type #车辆类型
self.displacement = displacement #车辆排量
def advance(self): #都有前进的技能
print("%s,出发了!"%self.brand)
class motorcycle(motor_vehicle): #摩托车是机动车
pass
m1 = motorcycle("春风","motorcycle",650) #实例化对象m1
m1.advance() #调用父类中对应的绑定方法
-------------------输出结果--------------------
春风,出发了!
2、组合的方式
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系。
比如摩托车有装备:
#定义装备类
class equipment: #摩旅需要的装备
def gps(self): #定义GPS这个技能
print("gps全程为您服务!")
#定义摩托车类
class motorcycle(motor_vehicle): #摩托车摩旅都需要装备,因而需要组合equipment类
def __init__(self,brand,motorcycle_type,displacement):
motor_vehicle.__init__(self,brand,motorcycle_type,displacement)
self.equipment = equipment() # 用equipment类产生一个装备,赋值给实例的equipment属性
def advance(self):#在自己这里定义新的advance,不再使用父类的advance,且不会影响父类
print("from motorcycle")
def fun(self): #定义新的功能
print("michael is a motorcycle trip")
m1 = motorcycle("春风","motorcycle",650) #实例化对象m1
m1.equipment.gps() #可以使用组合的类产生的对象所持有的方法
----------------输出结果------------------
gps全程为您服务!
注意:当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。
五、接口与归一化设计
1、什么是接口
1 =================第一部分:Java 语言中的接口很好的展现了接口的含义: IAnimal.java 2 /* 3 * Java的Interface很好的体现了我们前面分析的接口的特征: 4 * 1)是一组功能的集合,而不是一个功能 5 * 2)接口的功能用于交互,所有的功能都是public,即别的对象可操作 6 * 3)接口只定义函数,但不涉及函数实现 7 * 4)这些功能是相关的,都是动物相关的功能,但光合作用就不适宜放到IAnimal里面了 */ 8 9 package com.oo.demo; 10 public interface IAnimal { 11 public void eat(); 12 public void run(); 13 public void sleep(); 14 public void speak(); 15 } 16 17 =================第二部分:Pig.java:猪”的类设计,实现了IAnnimal接口 18 package com.oo.demo; 19 public class Pig implements IAnimal{ //如下每个函数都需要详细实现 20 public void eat(){ 21 System.out.println("Pig like to eat grass"); 22 } 23 24 public void run(){ 25 System.out.println("Pig run: front legs, back legs"); 26 } 27 28 public void sleep(){ 29 System.out.println("Pig sleep 16 hours every day"); 30 } 31 32 public void speak(){ 33 System.out.println("Pig can not speak"); } 34 } 35 36 =================第三部分:Person2.java 37 /* 38 *实现了IAnimal的“人”,有几点说明一下: 39 * 1)同样都实现了IAnimal的接口,但“人”和“猪”的实现不一样,为了避免太多代码导致影响阅读,这里的代码简化成一行,但输出的内容不一样,实际项目中同一接口的同一功能点,不同的类实现完全不一样 40 * 2)这里同样是“人”这个类,但和前面介绍类时给的类“Person”完全不一样,这是因为同样的逻辑概念,在不同的应用场景下,具备的属性和功能是完全不一样的 */ 41 42 package com.oo.demo; 43 public class Person2 implements IAnimal { 44 public void eat(){ 45 System.out.println("Person like to eat meat"); 46 } 47 48 public void run(){ 49 System.out.println("Person run: left leg, right leg"); 50 } 51 52 public void sleep(){ 53 System.out.println("Person sleep 8 hours every dat"); 54 } 55 56 public void speak(){ 57 System.out.println("Hellow world, I am a person"); 58 } 59 } 60 61 =================第四部分:Tester03.java 62 package com.oo.demo; 63 64 public class Tester03 { 65 public static void main(String[] args) { 66 System.out.println("===This is a person==="); 67 IAnimal person = new Person2(); 68 person.eat(); 69 person.run(); 70 person.sleep(); 71 person.speak(); 72 73 System.out.println("\n===This is a pig==="); 74 IAnimal pig = new Pig(); 75 pig.eat(); 76 pig.run(); 77 pig.sleep(); 78 pig.speak(); 79 } 80 } 81 82 java中的interface