面向对象 命名空间 继承

时间:2022-12-15 21:57:05

1.

面向对象 命名空间 继承面向对象 命名空间 继承
class Square:
    def __init__(self,side_len):
        self.len = side_len
    def perimeter(self):
        return 4*self.len
    def area(self):
        return self.len**2
s = Square(10)
print(s.perimeter())
print(s.area())
    
面向对象小练习

2.

# 类中的静态变量 可以被对象和类调用
# 对于不可变数据类型来说,类变量最好用类名操作
# 对于可变数据类型来说,对象名的修改是共享的,重新赋值是独立的
面向对象 命名空间 继承面向对象 命名空间 继承
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

静态属性就是直接在类中定义的变量
动态属性就是定义在类中的方法

其中类的数据属性是共享给所有对象的
而类的动态属性是绑定到所有对象的
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
# class Course:
#     language = 'chinese'
#     school = ['shanghai','beijing','tianjin']
#     def __init__(self,teacher,name,period,price):
#         self.teacher = teacher
#         self.name = name
#         self.period = period
#         self.price = price
#     def func(self):
#         pass
# python = Course('shang','python','6 month',20000)
# # print(python.language)
#
# print(python.school)
# python.school[0] = 'nanjing'
# print(python.school)
# python.language = 'english'
# print(python.language)
# print(Course.language)
类命名空间与对象、实例的命名空间

3.导入包的过程相当于类的实例化过程

# 包 —— __init__

# import package —— 类的实例化的过程

4.面向对象的组合用法

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

面向对象 命名空间 继承面向对象 命名空间 继承
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() 
#egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法
View Code
面向对象 命名空间 继承面向对象 命名空间 继承
# 人狗大战
class Dog:
    def __init__(self,name,aggr,hp,kind):
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.kind = kind

    def bite(self,person):
        person.hp -= self.aggr

class Person:
    def __init__(self,name,aggr,hp,sex):
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.sex = sex
        self.money = 0

    def attack(self,dog):
        dog.hp -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print("余额不足,请先充值")

class Weapon:
    def __init__(self,name,aggr,njd,price):
        self.name = name
        self.aggr = aggr
        self.njd = njd
        self.price = price

    def hand18(self,person):
        if self.njd > 0:
            person.hp -= self.aggr * 2
            self.njd -= 1

alex = Person('alex',0.5,100,'不详')
jin = Dog('金老板',100,500,'teddy')
w = Weapon('打狗棒',100,3,998)
# alex装备打狗棒
alex.money += 1000
alex.get_weapon(w)
print(alex.weapon)
print(alex.aggr)
alex.attack(jin)
print(jin.hp)
alex.weapon.hand18(jin)
print(jin.hp)
View Code
面向对象 命名空间 继承面向对象 命名空间 继承
from math import pi

class Circle:
    '''
    定义了一个圆形类;
    提供计算面积(area)和周长(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长

class Ring:
    '''
    定义了一个圆环类
    提供圆环的面积和周长的方法
    '''
    def __init__(self,radius_outside,radius_inside):
        self.outsid_circle = Circle(radius_outside)
        self.inside_circle = Circle(radius_inside)

    def area(self):
        return self.outsid_circle.area() - self.inside_circle.area()

    def perimeter(self):
        return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()


ring = Ring(10,5) #实例化一个环形
print(ring.perimeter()) #计算环形的周长
print(ring.area()) #计算环形的面积
组合用法--圆环
面向对象 命名空间 继承面向对象 命名空间 继承
class Teacher:
    def __init__(self,name,age,sex,birthday):
        self.name = name
        self.age = age
        self.sex = sex
        self.birthday = birthday
        self.course = Course('python','6 month','20000')
class Birthday:
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day
class Course:
    def __init__(self,course_name,period,price):
        self.name = course_name
        self.period = period
        self.price = price

b= Birthday(2018,1,16)
shang = Teacher('shang',18,'',b)
print(shang.name)
print(shang.birthday.year)
print(shang.birthday.month)
print(shang.course.price)
组合示例

5.面向对象的三大特性

继承:继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

 

面向对象 命名空间 继承面向对象 命名空间 继承
# 一个类 可以被多个类继承
class Father:
    pass
class Son1(Father):
    pass
class Son2(Father):
    pass

# python 里 一个类 可以继承多个父类
class A:
    pass
class B:
    pass
class C(A,B):
    pass
print(C.__bases__)#(<class '__main__.A'>, <class '__main__.B'>)
print(A.__bases__)#(<class 'object'>,)  # python3 -新式类# 没有继承父类默认继承object
View Code

继承与抽象(先抽象再继承)

面向对象 命名空间 继承

面向对象 命名空间 继承面向对象 命名空间 继承
# 父类中没有的属性 在子类中出现 叫做派生属性
# 父类中没有的方法 在子类中出现 叫做派生方法
# 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
# 如果父类 子类都有 用子类的
    # 如果还想用父类的,单独调用父类的:
    #       父类名.方法名 需要自己传self参数
    #       super().方法名 不需要自己传self
# 正常的代码中 单继承 === 减少了代码的重复
# 继承表达的是一种 子类是父类的关系

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp

    def eat(self):
        print('吃药回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        Animal.__init__(self,name,aggr,hp)  #
        self.kind = kind       # 派生属性
    def eat(self):
        Animal.eat(self)   # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类
        self.teeth = 2
    def bite(self,person):   # 派生方法
        person.hp -= self.aggr

jin = Dog('jin',100,500,'jiwa')
print(jin.name)
jin = Dog('金老板',100,500,'吉娃娃')
jin.eat()
print(jin.hp)

class Person(Animal):
    def __init__(self,name,aggr,hp,sex):
        Animal.__init__(self,name,aggr,hp)
        self.sex = sex       # 派生属性
        self.money = 0       # 派生属性

    def attack(self,dog):
        dog.hp -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print("余额不足,请先充值")
alex = Person('alex',1,2,None)
alex.eat()
print(alex.hp)

jin.bite(alex)
print(alex.hp)
单继承和派生

在python3中,子类执行父类的方法也可以直接用super方法.

面向对象 命名空间 继承面向对象 命名空间 继承
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()
View Code
面向对象 命名空间 继承面向对象 命名空间 继承
class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def eat(self):
        print('吃药回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        super().__init__(name,aggr,hp)  # 只在新式类中有,python3中所有类都是新式类
        self.kind = kind       # 派生属性
    def eat(self):print('dog eating')

jin = Dog('金老板',200,500,'teddy')
print(jin.name)
jin.eat()
super(Dog,jin).eat()
View Code

 

面向对象 命名空间 继承面向对象 命名空间 继承
class A:
    def func(self):print('A')
class B:
    def func(self): print('B')
class C:
    def func(self): print('C')
class D(A,B,C):#继承就近原则
      pass
      # def func(self): print('C')
d = D()
d.func()
多继承就近原则
# 新式类 继承object类的才是新式类 广度优先
# 经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
# print(D.mro())
# D.mro()

# 单继承 : 子类有的用子类 子类没有用父类
# 多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
# 经典类中 深度优先
# 新式类中 广度优先
# python2.7 新式类和经典类共存,新式类要继承object
# python3 只有新式类,默认继承object
# 经典类和新式类还有一个区别 mro方法只在新式类中存在
# super 只在python3中存在
# super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的
面向对象 命名空间 继承面向对象 命名空间 继承
class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
View Code