Python基础复习09_面向对象特性

面向对象特性

1. 继承

Outline
·继承概念
·单继承/多继承
·子类重写/调用父类的同名属性和方法
·多层继承
·super()
·私有属性和私有方法

1.1 继承的概念

继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法
·拓展:经典类(旧式类)与新式类

·不由任意内置类型派生出的类称为经典类
·也即:继承了object类的是新式类,没有继承object类的是经典类
·注意:在python3中所有自定义类的基类都会默认继承object类,也即py3中所有类都是新式类
# 经典类
class ClassName:
    ......
    ......
    
# 新式类
class ClassName(object):
    ......
    ......

·在python3中,所有类默认继承object类,object类是顶级类或基类;其他自类叫做派生类

1.2 单继承/多继承

·注意:需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

# 单继承 && 多继承
class Python:
    code_language = ''
    def __init__(self):
        self.code_language = 'Python'
    def code(self):
        print(f"I'm coding in {self.code_language}")

class Java:
    code_language = ""
    def __init__(self):
        self.code_language = 'Java'
    def code(self):
        print(f"I'm coding in {self.code_language}")

# 单继承
class subLang(Python):
    pass

# 多继承
class sub2Lang(Java,Python):
    pass

lang1 = subLang()
lang1.code()
lang2 = sub2Lang()
lang2.code()
I'm coding in Python
I'm coding in Java
1.3 子类重写/调用父类同名方法和属性

·子类和父类具有同名属性和方法时,默认使用子类的

# 重写父类方法
class sub3Lang(Java,Python):
    def __init__(self):
        self.code_language = 'Scala'
    def code(self):
        print("code by %s" % self.code_language)
        
lang3 = sub3Lang()
lang3.code()
print("--"*5)

# 调用父类方法
class sub4Lang(Java,Python):
    def __init__(self):
        self.code_language = 'scala'
    
    def code(self):
        #如果先调用了父类属性和方法,父类属性会覆盖子类属性,所以在调用属性前,先调用子类的初始化
        self.__init__()
        print("code by %s" % self.code_language)

    # 调用父类方法,为了保证调用到的是父类属性,在调用方法前先调用父类的初始化
    def codeByPython(self):
        Python.__init__(self)
        Python.code(self)
        
    def codeByJava(self):
        Java.__init__(self)
        Java.code(self)
        
lang4 = sub4Lang()
lang4.code()
lang4.codeByPython()
lang4.codeByJava()
lang4.code()
code by Scala
----------
code by scala
I'm coding in Python
I'm coding in Java
code by scala
1.4 多层继承
# 多层继承
class sub5Lang(sub4Lang):
    pass

lang5 = sub5Lang()
lang5.code()
lang5.codeByPython()
lang5.codeByJava()
code by scala
I'm coding in Python
I'm coding in Java
1.5 super()
1.5.1 __mro__

·查看一个类的父类及层级关系(继承层级顺序)

# __mro__
print(sub5Lang.__mro__)
print(sub4Lang.__mro__)
print(subLang.__mro__)
(<class '__main__.sub5Lang'>, <class '__main__.sub4Lang'>, <class '__main__.Java'>, <class '__main__.Python'>, <class 'object'>)
(<class '__main__.sub4Lang'>, <class '__main__.Java'>, <class '__main__.Python'>, <class 'object'>)
(<class '__main__.subLang'>, <class '__main__.Python'>, <class 'object'>)
1.5.2 super()方法

作用:调用父类方法
语法:

# 带参形式
super(当前类名,self).funName()

# python3中可以使用简化写法
super().funName()

·注意:super可以自动查找父类,调用顺序遵循__mro__的顺序,适合单继承使用。

1.6 私有权限
1.6.1 定义私有属性和方法

·在python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或方法不继承给子类
·方法:在属性名/方法名前面加两个下划线
·注意:私有属性和私有方法只能在类中访问和修改

# 定义私有属性和方法
class Father():
    def __init__(self):
        self.house = 'BJ2huan'
        self.__money = "9999999$"
    def __giveMoney(self):
        print(f"give u {self.__money}")
        
man = Father()
man.__giveMoney()
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-15-7260ef001b55> in <module>
      8 
      9 man = Father()
---> 10 man.__giveMoney()


AttributeError: 'Father' object has no attribute '__giveMoney'
print(man.__money)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-16-0f10097db91d> in <module>
----> 1 print(man.__money)


AttributeError: 'Father' object has no attribute '__money'
1.6.2 获取和修改私有属性值

一般定义get_xx来获取私有属性,定义set_xx来修改私有属性

class dad():
    def __init__(self):
        self.__money = '$9999999999'
    
    def get_money(self):
        return self.__money
    
    def set_money(self,money):
        self.__money = money
    
man = dad()
print(man.get_money())
man.set_money('¥999999')
print(man.get_money())
$9999999999
¥999999

2. 多态

·定义:多态是一种使用对象的方式;子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行效果
·好处:调用灵活,让代码可重用性提高
·实现步骤:

1.定义父类,提供公共方法
2.定义子类,重写父类方法
3.将子类对象传给调用者,可以看到不同子类执行效果不同
class Dog:
    def work(self):
        pass

class PoliceDog(Dog):
    def work(self):
        print("Follow and find the animy")
        
class DrugDog(Dog):
    def work(self):
        print("Find the drugs")
        
class Policeman:
    def workWithDog(self,dog):
        dog.work()
        
police_dog = PoliceDog()
drug_dog = DrugDog()

police = Policeman()
police.workWithDog(police_dog)
police.workWithDog(drug_dog)
Follow and find the animy
Find the drugs

3. 类属性和实例属性

3.1 类属性
3.1.1 设置&访问类属性

·类属性就是类对象所拥有的属性,它被该类的所有实例对象 共有
·类属性可以使用类对象实例对象访问

class Cat:
    brother = 'tiger'
    
daJu = Cat()
xiaoHua = Cat()

print(f"cat's bro : {Cat.brother} \n\
daju's bro:{daJu.brother} \n\

xiaohua's bro: {xiaoHua.brother}")
cat's bro : tiger 
daju's bro:tiger 
xiaohua's bro: tiger

·类属性的优点

  • 记录的某项数据 始终保持一致时,则定义类属性。
  • 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有 ,仅占用一份内存更加节省内存空间
3.1.2 修改类属性

·类属性只能通过类对象来修改,而不能通过实例对象来修改,如果通过实例对象来修改类属性,实际上表示创建了一个实例属性。

# 修改类属性
Cat.brother = 'xiba'
print(f"cat's bro : {Cat.brother} \n\
daju's bro:{daJu.brother} \n\
xiaohua's bro: {xiaoHua.brother}")
print("---"*10)
# 不能通过实例对象修改类属性
daJu.brother = 'cat'
print(f"cat's bro : {Cat.brother} \n\
daju's bro:{daJu.brother} \n\
xiaohua's bro: {xiaoHua.brother}")
cat's bro : xiba 
daju's bro:cat 
xiaohua's bro: xiba
------------------------------
cat's bro : xiba 
daju's bro:cat 
xiaohua's bro: xiba
3.2 实例属性
class Cat:
    def __init__(self):
        self.age = 5
    def print_info(self):
        print(self.age)
        
shabi = Cat()
print(shabi.age)
shabi.print_info()
print(Cat.age) # 报错:实例属性不可以通过类对象访问
5
5



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-29-f947428b7ef1> in <module>
      8 print(shabi.age)
      9 shabi.print_info()
---> 10 print(Cat.age) # 报错:实例属性不可以通过类对象访问


AttributeError: type object 'Cat' has no attribute 'age'

4. 类方法和静态方法

4.1 类方法
4.1.1 类方法的特点

·需要使用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls为第一个参数

4.1.2 类方法的使用场景

·当方法中需要使用类对象(如访问私有类属性等)时,定义类方法
·类方法一般需要和类属性配合使用

class Doggie:
    __master = 'jcl'
    
    @classmethod
    def get_mastername(cls):
        return cls.__master
    
wangcai = Doggie()
print(wangcai.get_mastername())
jcl
4.2 静态方法
4.2.1 静态方法特点
  • 需要使用装饰器@staticmethod来修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)
  • 静态方法也能通过实例对象类对象去访问。
4.2.2 静态方法使用场景
  • 当方法中既不需要使用实例对象(如实例对象或属性),也不需要使用类对象(类对象/属性/创建实例等)时,定义静态方法
  • 取消不需要的参数传递,有利于减少不必要地内存占用和性能消耗
class Doggg:
    @staticmethod
    def print_info():
        print("This is a dog class,try to create a dog object")
        
wangcai = Doggg()

wangcai.print_info()
Doggg.print_info()
This is a dog class,try to create a dog object
This is a dog class,try to create a dog object

Summary

面向对象三大特性:

  • 封装
    • 将属性和方法书写到类的里面的操作即为封装
    • 封装可以为属性和方法添加私有权限
  • 继承
    • 子类默认继承父类的所有属性和方法
    • 子类可以重写父类属性和方法
  • 多态
    • 传入不同的对象,产生不同的结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值