python之面向对象2
一、类命名空间与对象、实例的命名空间
常见一个类就会创建一个类的名称空间,用来储存类中定义的所有名字,这些名字成为类的属性
而类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
面相对象的组合用法:
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
class Weapon: def prick(self, obj): # 这是该装备的主动技能,扎死对方 obj.life_value -= 500 # 假设攻击力是500 class Person: # 定义一个人类 role = 'person' # 人的角色属性都是人 def __init__(self, name): self.name = name # 每一个角色都有自己的昵称; self.weapon = Weapon() # 给角色绑定一个武器; egg = Person('egon') egg.weapon.prick()
from math import pi class Circular: def __init__(self,radius): self.radius=radius def area(self): return self.radius **2 * pi def perimeter(self): return 2 * self.radius * pi circu=Circular(10) print(circu.area()) print(circu.perimeter())
class 正方形: def __init__(self,length_of_side): self.length_of_side = length_of_side def square(self): '面积' return self.length_of_side * self.length_of_side def perimeter(self): '周长' return self.length_of_side * 4 正方形2 = 正方形(2) print(正方形2.square()) print(正方形2.perimeter())
from math import pi class Circular: def __init__(self,radius): self.radius=radius def area(self): return self.radius **2 * pi def perimeter(self): return 2 * self.radius * pi circu=Circular(10) print(circu.area()) print(circu.perimeter()) class Ring: def __init__(self,outside_radius,inside_radius): self.outside_circular=Circular(outside_radius) self.inside_circular=Circular(inside_radius) def area(self): return self.outside_circular.area()-self.inside_circular.area() def perimeter(self): return self.outside_circular.perimeter()+self.inside_circular.perimeter() ring = Ring(10,5) #实例化一个环形 print(ring.perimeter()) #计算环形的周长 print(ring.area())
二、用组合的方式建立了类与组合的类之间的关系
#老师 课程 生日 class Course: def __init__(self,name,period,price): self.name = name self.period = period self.price = price class Birth: def __init__(self,year,month,day): self.year = year self.month = month self.day = day class Teacher: def __init__(self,name,salary,boy_friend,python): self.name = name self.salary = salary self.bf = boy_friend self.course = python python = Course('python','6 months',20000) egg = Teacher('egon',200,'yuan',python) print(egg.bf) print(egg.name) print(egg.course.name) egg_birth = Birth(1965,2,2) print(egg_birth.year) egg.birth = egg_birth print('***',egg.birth.year)
三、面向对象的三大特征
1、继承
class Animal: #父类 基类 超类 def __init__(self,name,life_value,aggr): self.name = name self.life_value = life_value self.aggr = aggr class Person(Animal): #子类 派生类 pass class Dog(Animal): #子类 派生类 pass egg = Person('egon',1000,50) print(egg.name) print(egg.aggr)
python2
class Dad: #经典类
class Dag(object) #新式类
python3
class Dad == class Dag(object) #新式类
class Animal: #父类 基类 超类 def __init__(self,name,life_value,aggr): self.name = name self.life_value = life_value self.aggr = aggr #攻击力 def eat(self): self.life_value += 10 class Person(Animal): #子类 派生类 def __init__(self,money,name,life_value,aggr): super().__init__(name,life_value,aggr) self.money = money #派生属性 def attack(self,enemy): #人的派生方法 enemy.life_value -= self.aggr class Dog(Animal): #子类 派生类 def __init__(self,breed,name,life_value,aggr): #Animal.__init__(self,name,life_value,aggr) #让子类执行父类的方法,就是父类名.方法名(参数),连self也得传 super().__init__(name,life_value,aggr) #super关键字——新式类 #super(Dog,self).__init__(name,life_value,aggr) #super关键字关键字——新式类 self.breed = breed def bite(self,person): #狗的派生方法 person.life_value -= self.aggr def eat(self): # 父类方法的重写 super().eat() print('dog is eating~~~ ') ha2 = Dog('牛头梗','旺财',20000,100) print(ha2.life_value) ha2.eat() print(ha2.life_value) # super(Dog,ha2).eat() #调用父类的 print(ha2.life_value)
在继承中
继承的语法:
class 类名(父类名):
想在子类中实现调用父类的方法
在类内 ——super(子类名,self).方法名()
在类外面 ——super(子类名,对象名).方法名()
如果不指定继承的父类,默认继承object
子类可以使用父类的所有属性和方法
如果子类有自己的方法就执行自己的的
如果是子类没有的方法就执行父类的
如果子类父类都没有这个方法就报错
继承、抽象、派生
继承 是从大范围到小范围
抽象 小范围到大范围
派生 就是在父类的基础上又产生子类——派生类
父类里没有的 但子类有的 ——派生方法
派生属性
方法的重写
父类里有的方法,在子类里重新实现
class A: def hahaha(self): print('A') class B(A): def hahaha(self): super().hahaha() #super(B,self).hahaha() #A.hahaha(self) print('B') a = A() b = B() b.hahaha() super(B,b).hahaha()
继承:
继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义
了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
from abc import ABCMeta,abstractmethod class Payment(metaclass = ABCMeta): #metaclass --> 元类 @abstractmethod def pay(self,money):pass class Applepay(Payment): def pay(self,money): print('apple pay 支付了%s'%money) class Alipay(Payment): def pay(self,money): print('支付宝 支付了%s'%money) class Wechatpay(Payment): def fuqian(self,money): print('微信支付了%s'%money) def payment(pay_obj,money): pay_obj.pay(money) # apple1 = Applepay() # ali1 = Alipay() # wechat1 = Wechatpay() # payment(wechat1,200)
接口类
约束继承接口类的子类必须实现被abstractmethod装饰的方法
在接口类中不要做实现
接口类不能被实例化
四、抽象类
抽象 : 从小范围到大范围
from abc import ABCMeta,abstractmethod class Animal(metaclass=ABCMeta): @abstractmethod def eat(self): print('打开粮食的袋子') print('放一个吃饭的碗') print('把粮食倒在碗里') @abstractmethod def sleep(self): pass class Dog(Animal): def eat(self): super().eat() print('dog is eating') def sleep(self): print('dog is sleeping')
当几个子类的父类 有相同的功能需要被实现的时候 就用抽象类
当几个子类 有相同的功能 但是实现各不相同的时候 就用接口类
约束
接口类和抽象类在java里面的区别
接口类支持多继承
抽象类只支持单继承
class Animal: def swim(self): pass def fly(self): pass def walk(self): pass from abc import ABCMeta,abstractmethod class Fly_Animal(Animal,metaclass=ABCMeta): @abstractmethod def fly(self):pass class Swim_Animal(Animal,metaclass=ABCMeta): @abstractmethod def swim(self):pass class Walk_Animal(Animal,metaclass=ABCMeta): @abstractmethod def walk(self):pass class Dog(Walk_Animal,Swim_Animal): def walk(self):pass def swim(self):pass def eat(self):pass def sleep(self):pass class Parrot(Fly_Animal,Walk_Animal): pass d = Dog()
抽象类
在Python里 默认是有的
父类的方法 子类必须实现
抽象类 不能被实例化
抽象类内的方法 可以被简单实现
接口类(在抽象类的基础上)
在python里 默认是没有的
接口类中的方法 不能被实现
原则:抽象类最好不要用多继承,而接口类可以
五、多继承
class A(object): def test(self): print('from A') class B(A):pass # def test(self): # print('from B') class C(A): def test(self): print('from C') class E(B):pass # def test(self): # print('from E') class F(C):pass # def test(self): # print('from F') class H: def test(self): print('from H') class I(H): def test(self): print('from I') class J(H): def test(self): print('from J') class D(E,F,I,J):pass d = D() d.test() print(D.mro())
六、多态性
多态指的是:一类实物有多种状态
class Animal: # def eat(self):pass # # class Cat(Animal):pass # class Dog(Animal):pass # class Pig(Animal):pass
class Animal:pass class Cat(Animal): def eat(self): print('cat eat') class Dog(Animal): def eat(self): print('dog eat') def eat_func(a): a.eat() c = Cat() eat_func(c) d = Dog() eat_func(d)
python自带多态:
1 同一类事物的不同状态
2 操作的时候不需要关心这个对象的数据类型,只要去用就可以了