继承

隐藏内部实现细节,对外提供操作方式。

权限控制:是通过对属性或方法添加单下划线、双下划线以及首尾双下划线来实现。

单下划线开头:以单下划线开头的属性或方法表示protected受保护的成员,这类成员被视为仅内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问。

双下划线开头:表示priavte私有的成员,这类成员只允许定义该属性或方法的类本身进行访问。

首尾双下划线:一般表示特殊的方法。

class Student():
    # 双下划线
    def __init__(self,name,age,gender):
        self._name=name  # self._name 受保护的 只有类和子类可以访问
        self.__age=age   # self.__age 表示私有的 只有类本身可以访问
        self.gender=gender # 普通的实例属性,类的内部,外部,及子类都可以访问

    # 受保护的
    def _func1(self):
        print('子类和本身可以访问')

    # 私有的
    def __func2(self):
        print('止呕定义的类可以访问')

    # 普通的实例方法
    def show(self):
        self._func1()  # 类本身访问受保护的方法
        self.__func2() # 类本身访问私有方法
        print(self._name) # 受保护的实例属性
        print(self.__age) # 私有的实例属性


stu=Student('张三',25,'')
print(stu._name)
# print(stu.__age) # 私有的实例属性不能访问,报错
stu._func1()
# stu.__func2() # 私有的实例方法不能访问,报错

# 私有的属性和方法可以通过以下方法访问
print(stu._Student__age)
stu._Student__func2()

print(dir(stu))

属性的设置

class Student():
    def __init__(self,name,gender):
        self.name=name
        self.__gender=gender


    # 使用@property 修饰方法 将方法转换成属性使用  只能查看值,不能修改值
    @property
    def gender(self):
        return self.__gender

    # 将gender这个属性设置可修改
    @gender.setter
    def gender(self,gender):
        if gender!='' and gender !='':
            print('性别有误')
            self.__gender=''
        else:
            self.__gender=gender

stu=Student('张三','')
print(stu.name,stu.gender)  # stu.gender 就会执行gender()方法
stu.gender=''
print(stu.name,stu.gender)

继承

1,在python中一个子类可以继承N多个父类。

2,一个父类也可以拥有N多个子类。

3,如果一个类没有继承任何类,那么这个类默认继承的是object类。

继承的语法结构:

class 类名(父类1,父类2,...父类N):
    pass
# 默认继承object
class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print(f'大家好,我叫{self.name},年龄:{self.age}')

class Student(Person):
    def __init__(self,name,age,stuno):
        super().__init__(name,age) #调用父类的初始化方法
        self.stuno=stuno

class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age)
        self.department=department

stu=Student('张三',10,'1002')
stu.show()
doc=Doctor('李四',34,'外科')
stu.show()
class Father1():
    def __init__(self,name):
        self.name=name

    def show1(self):
        print('这是父类1的方法')

class Father2():
    def __init__(self,age):
        self.age=age

    def show2(self):
        print('这是父类2的方法')

class Son(Father1,Father2):
    def __init__(self,name,age,gender):
        Father1.__init__(self,name)
        Father2.__init__(self,age)
        self.gender=gender

son=Son('张三',20,'')
son.show1()
son.show2()

方法重写

子类继承了父类就拥有了父类中公有成员和受保护的成员。

父类的方法并不能完全适合子类的需求,这个时候子类就可以重写父类的方法。子类在重写父类的方法时,要求方法的名称必须与父类的方法的名称相同,在子类重写后的方法中可以通过super().XXX()调用父类中的方法。

# 默认继承object
class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print(f'大家好,我叫{self.name},年龄:{self.age}')

class Student(Person):
    def __init__(self,name,age,stuno):
        super().__init__(name,age) #调用父类的初始化方法
        self.stuno=stuno

    def show(self):
        super().show() # super().方法名调用父类中的方法
        print('这是子类重写的方法')

class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age)
        self.department=department

    def show(self):
        #super().show()
        print(f'子类重写的方法,{self.name},{self.age}')

stu=Student('张三',10,'1002')
stu.show()  #调用子类自有的方法
doc=Doctor('李四',34,'外科')
doc.show()  #调用子类自有的方法

多态

指的是“多种形态”,即便不知道一个变量引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法。

在程序运行过程中根据变量所引用对象的数据类型,动态决定 调用哪个对象中的方法。

Python语言中的多态,根本不关心对象的数据类型,也不关心类之间是否存在继承关系,只关心对象的行为(方法)。只要不同的类中有同名的方法,即可实现多态。

class Person():
    def eat(self):
        print('人吃米饭')

class Cat():
    def eat(self):
        print('猫吃鱼')

class Dog():
    def eat(self):
        print('狗吃骨头')

def fun(obj):  # 这里不知道obj具体的数据类型,只需要obj有同名的方法
    obj.eat()

per=Person()
cat=Cat()
dog=Dog()

fun(per)
fun(cat)
fun(dog)

object类

所有类直接或间接的父类

所有类都拥有object类的属性和方法

object类中特殊的方法 功能描述
__new__() 由系统调用,用于创建对象
__init__() 创建对象时手动调用,用于初始化对象属性值
__str__() 对象的描述,返回值是str类型,默认输出对象的内存地址

 

 

 

 

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print(f'大家好,{self.name},{self.age}')

    # 重写父类中__str__()方法
    def __str__(self):
        return '我是子类中的方法,重写了父类中的方法'

# 创建Person类的对象
per=Person('张三',20) #创建对象时自动会调用__init__()
print(dir(per))

print(per) #自动调用了__str__方法  <__main__.Person object at 0x000000A241D77290>
print(per.__str__())

 特殊方法

运算符 特殊方法 功能描述
+ __add__() 执行加法运算
- __sub__() 执行减法运算
<  <= == __lt__()  __le__()  __eq__() 执行比较运算
>  >=  != __gt__()  __ge__()  __ne__() 执行比较运算
*  / __mul__()  __truediv__() 执行乘法运算,非整除运算
%  // __mod__()  __floordiv__() 执行取余运算,整除运算
** __pow__() 执行幂运算

 

 

 

 

 

 

 

 

a=10
b=20
print(dir(a))
print(f'a={a},b={b}')
print(a+b)
print(f'{a}+{b}',a.__add__(b))
print(f'{a}-{b}',a.__sub__(b))
print(f'{a}<{b}',a.__lt__(b))
print(f'{a}<={b}',a.__le__(b))
print(f'{a}=={b}',a.__eq__(b))

print(f'{a}>{b}',a.__gt__(b))
print(f'{a}>={b}',a.__ge__(b))
print(f'{a}!={b}',a.__ne__(b))

print(f'{a}*{b}',a.__mul__(b))
print(f'{a}/{b}',a.__truediv__(b))
print(f'{a}%{b}',a.__mod__(b))
print(f'{a}//{b}',a.__floordiv__(b))
print(f'{a}**{b}',a.__pow__(b))

特殊属性

特殊属性 功能描述
obj.__dict__ 对象的属性字典
obj.__class__ 对象所属的类
class.__bases__ 类的父类元组
class.__base__ 类的父类
class.__mro__ 类的层次结构
class._subclasses__() 类的子类列表

 

 

 

 

 

 

 

class A():
    pass
class B():
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age

a=A()
b=B()
c=C('tom',20)

print('对象a的属性字典',a.__dict__) # {}
print('对象b的属性字典',b.__dict__) # {}
print('对象c的属性字典',c.__dict__) # {'name': 'tom', 'age': 20}

print('对象a的所属类',a.__class__)
print('对象b的所属类',b.__class__)
print('对象c的所属类',c.__class__)

print('A类的父类元组',A.__bases__)
print('B类的父类元组',B.__bases__)
print('C类的父类元组',C.__bases__)

print('A类的父类',A.__base__)
print('B类的父类',B.__base__)
print('C类的父类',C.__base__)

print('A类的层次结构',A.__mro__)
print('B类的层次结构',B.__mro__)
print('C类的层次结构',C.__mro__)

print('A类的子类列表',A.__subclasses__)
print('B类的子类列表',B.__subclasses__)
print('C类的子类列表',C.__subclasses__)

 

 posted on 2023-12-20 23:01  会飞的金鱼  阅读(19)  评论(0)    收藏  举报