python学习笔记(十二)面向对象2

面向对象

面向对象三大特点

封装:既是对数据封装,又是对处理数据的方法的封装
继承:强调的是父子类之间的关系
多态:不同的对象调用相同的方法,有不同的响应。

类的继承

相关概念

继承:父类的属性和方法,子类直接拥有,称为继承。
派生:子类在父类的基础上衍生出新的特征(属性和行为)
总结:其实他们是一回事,只是描述问题的侧重点不同(继承侧重相同点,派生侧重不同点)

可以简单理解 儿子 相对于父亲 可以对父亲的家产创新
也可以变卖 可以取其精华取其糟粕 可以青出于蓝而胜于蓝
QAQ

继承语法

# class Animal:
# 当没有写父类时,默认继承自object
# 定义一个动物类
class Animal(object):
    def __init__(self, name):
        self.name = name

    def run(self):
        print('小动物们一天到晚到处乱跑')
# 狗 继承自 动物  狗也是动物     
class Dog(Animal):
 	def eat(self):
      	print('小狗喜欢啃骨头')   
    
# 创建一个狗  对象
d = Dog('旺财')

# 继承的属性
print(d.name)
# 继承的方法
d.run()

# 添加新的属性
d.age = 2
# 添加的方法
d.eat()       

方法重写

当对于父类的方法不满意的时候 可以进行重写
重写之后 父类的方法就会失效 自己重写的方法生效

class Aniaml:
    def eat(self):
        print('小动物都喜欢吃东西')

    def run(self):
        print('小动物喜欢跑个不停')
        
class Cat(Aniaml):
    # 完全不合适,覆盖重写
    def run(self):
        print('猫喜欢走猫步')

	# 不完全合适,需要修改完善
    def eat(self):
        # 调用父类的方法
        # Aniaml.eat(self)        # 不建议使用
        # super(Cat, self).eat()      # 老的写法
        super().eat()               # 新的写法,推荐
        print('猫喜欢吃鱼') 
        
c = Cat()
c.eat()
c.run()

多继承

一个类可以有多个父类,即可以拥有多个类的特征

class A:
    def eat(self):
        print('eat func in class A')

class B:
    def run(self):
        print('run func in class B')

	def eat(self):
		print('eat func in class B')
        
class C(A, B):
    def eat(self):
        # 这样写会按照默认顺序查找父类的方法
        # super().eat()
        # 可以明确指定调用哪个父类的方法
        B.eat(self)    
 
c = C()
c.eat()
c.run()

继承链

class A(object):
    def foo(self):
        print('A foo')
            
class B(object):
    def foo(self):
        print('B foo')

    def bar(self):
        print('B bar')
    
class C1(A, B):
    pass

class C2(A, B):
    def bar(self):
        print('C2-bar')

class D(C1, C2):
    pass

d = D()

d.foo()
d.bar()

# __mro__类属性,记录了继承链的查找顺序
# 一旦找到,立即停止并返回
# 按照广度优先的原则进行查找
for i in D.__mro__:
    print(i)  

访问权限

class Person:
    def __init__(self, name, age):
        self.name = name
        # 定义私有属性
        self.__age = age
        
p = Person('王大花', 18)

# 公有属性:可以在类外使用
print(p.name)
# 私有属性:不能再类外使用
# print(p.__age)

# 实现原理:私有属性默认会在前面加 '_类名' 前缀
# 可以通过下面的方式访问私有属性,但是强烈不建议
# print(p._Person__age)
print(p.__dict__)

class Man(Person):
    def introduce(self):
        # 可以在子类中使用
        print(self.name)
        # 也不能在子类中使用
        # print(self.__age)    
 
m = Man('二狗', 20)
m.introduce()

总结
公有属性:在类的内部、外部、子类中都可以使用
私有属性:只能在类的内部使用,类外及子类中都不能使用
实现原理:默认在’_'开头的属性前添加’类名’的前缀

类属性

class Person:
    # 类属性
    nation = 'china'

    # 限制对象可以使用的属性,可以提升访问效率
    # 只可以使用这么多
    __slots__ = ('name', 'age')

    def __init__(self, name):
        # 成员属性
        self.name = name
        
xiaoming = Person('小明')
xiaohong = Person('小红')
print(xiaoming.name)
print(xiaohong.name)
        
# 查看对象的类名
print(xiaoming.__class__)

# 通过类名进行访问
print(Person.nation)

# 查看类的名字
print(Person.__name__)

# 查看父类元组
print(Person.__bases__)

# 类相关的信息
print(Person.__dict__)

# 查看继承链顺序
print(Person.__mro__)

xiaoming.age = 20
# 不能添加,因为没有在Person.slots类属性中
# xiaoming.height = 180

# 显示对象能够使用的属性
print(Person.__slots__)

类方法

class Person:
    # 成员方法:通过对象调用
    def eat(self):
        print('能吃是福')

    # 类方法:通过类名调用
    @classmethod
    def test(cls):
        # cls:表示当前类
        print(cls)

    # 可以创建对象 或 简单的创建对象
    @classmethod
    def create(cls):
        p = cls()
        p.age = 1
        return p
    
p = Person()
p.eat()

Person.test()

p2 = Person.create()
print(p2)    
p2.eat()

作用:

可以创建对象 或 简洁的创建对象
可以对外提供简单易用的接口

静态方法

class Person:
    # 定义静态方法:也是通过类名调用,但是没有第一个表示当前类的参数
    @staticmethod
    def test():
        print('静态方法 test')

    # 可以创建对象
    @staticmethod
    def create():
        return Person()
  

class Man(Person):
    @staticmethod
    def test():
        # 无法使用super调用父类方法
        # 只能通过类名调用
        Person.test()
        
Person.test()

p = Person.create()
print(p)

Man.test()

总结
方式可以静态方法解决的问题都可以使用类方法进行解决
静态方法中无法使用super
静态方法中没有cls参数

多态特性

说明:不同的对象调用相同的方法,有不同的响应

示例:

class Animal:
    def run(self):
        print('小动物走路姿势各不相同')
        
class Dog(Animal):
	def run(self):
      	print('狗喜欢撒欢疯跑')

class Cat(Animal):
	def run(self):
      	print('猫走的是猫步')
      	
def func(obj):
	# 判断某个对象是否拥有某个属性
    if hasattr(obj, 'run'):
    	obj.run()
    else:
    	print('类型有误')
    	
func(Dog())
func(Cat())

对象支持字典操作

说明:将对象当做字典操作时,会自动触发相关的魔术方法

示例:

class Person:
    # 当做字典操作:设置属性时
    def __setitem__(self, key, value):
        # print(key, value)
        self.__dict__[key] = value

    # 当做字典操作:获取属性时
    def __getitem__(self, item):
        # print(item)
        return self.__dict__.get(item)

    # 当做字典操作:删除属性时
    def __delitem__(self, key):
        # print(key)
        self.__dict__.pop(key)
        # del self.__dict__[key]
        
p = Person()

# p.name = '大花'
p['name'] = '大花'

# print(p.name)
print(p['name'])

# del p.name
del p['name']
print(p.dict)       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值