面向对象--继承、封装、多态

复制代码
from math import pi
#def 定义一个函数,自带self形参
#class 定义一个类,类名一般首字母大写
#   类中包含两中内容:1、 静态属性(变量); 2、动态属性(方法、函数),函数自带形参 self
class Test:
    s1 = 'test'

    def __init__(self, a):
        self.aa = a
        print('init', self, self.aa) # init <__main__.Test object at 0x7fdb6498ffa0>

    def T1(self, b):
        return b

# 类名的用处:1、访问静态和动态属性;2、创造一个对象;
print(Test.s1)# test
print(Test.T1(1, 2))# 2, 直接调用类的时候,因为init会默认执行,所以需要给init传值

print(Test.__dict__)# 类的内容以字典形式存储,内置函数dict可查看


obj = Test('aaa')# 对象 = 类名(init所需参数)
print(obj) # init <__main__.Test object at 0x7fdb6498ffa0>
print(obj.aa) # aaa
#1、初始化的时候默认执行init, 并把init对象存在self中;
#2、初始化之后,会把init返回给obj,所以 init 内部print的self对象和print obj对象是同一个;

re = obj.T1('b')
print(re)

#对象嵌套
class circular():
    def __init__(self, r):
        self.r = r

    def C(self):
        print(self.r)
        return 2 * pi * self.r

    def S(self):
        return pi * self.r ** 2

class ring():
    def __init__(self, in_r, out_r):
        self.in_r = circular(in_r)
        self.out_r = circular(out_r)

    def C(self):
        return self.out_r.C() - self.in_r.C()

    def S(self):
        return self.out_r.S() - self.in_r.S()

a = ring(5, 10)
print(a.C())

#三大特性:继承、封装、多态
#继承:
    # 1、解决代码的重复性

# 单继承
class C1():# 父类、基类、超类
    def __init__(self, c1):
        self.c1 = c1
class C2(C1):# 子类、派生类 括号里只能传类名
    def __init__(self, c2):
        self.c2 = c2
        super().__init__(5)# 当父、子类均有init(或重名)时,使用父类init需要 super() 加载父类init
print(C2.__bases__) # (<class '__main__.C1'>,)  查看父类
print(C1.__bases__) # (<class 'object'>,) 没有父类就是object,object是所有类的父类

test = C2(3)
print(test.c2)# 3
print(test.c1)# 5

# 多继承
class B1():
    def __init__(self, b1):
        self.b1 = b1
class B2():
    def __init__(self, b2):
        self.b2 = b2
class B3(B1, B2):
    def __init__(self, b3):
        self.b3 = b3
        B1.__init__(self, 8)
        B2.__init__(self, 9)# 多继承需要指定父类,且传参要写self

test = B3(7)
print(test.b3)
print(test.b2)


#抽象类: 规范所有继承这个类的子类必须实现 @abstractmethod 装饰的方法
    # 在类的位置指定 metaclass=ABCMeta
    # 在指定的方法上加 @abstractmethod 装饰器

# 接口类(Java知识点): 多继承抽象类,两种类都不能被实例化
from abc import abstractmethod, ABCMeta

class Print(metaclass=ABCMeta):
    @abstractmethod
    def Print(self, str):pass # 父类约束

class log1(Print):# 子类继承父类受父类约束
    def Print(self, str):
        print(str)

class log2(Print):
    # def shuchu(self, str): # 没有定义Print方法,实例化会抛异常
    def Print(self, str):
        print(str)

def Print(obj, str):obj.Print(str)

L1 = log1()
Print(L1, 'haha')
L2 = log2()
# Print(L2, 'L2')
复制代码

 

复制代码
#钻石继承
class A:
    def func(self):
        print('A')

class B(A):pass
    # def func(self):
    #     print('B')
# B 和 C 类都继承A,当B没有func()对象时,遵循广度优先算法;如果B 和 C 继承不同类时,遵循深度优先
class C(A):
    def func(self):
        print('C')

class D(B, C):pass
    # def func(self):
        # print('D')

d = D()
d.func()
# 类名.mro() 可以直接将继承顺序输出,super()父类继承也遵循该顺序
print(D.mro())# [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

#多态,Java类需指定参数的类型,将多种类型定义到一个类中,后续类继承定义了多种数据类型的类,即为多态;
    #python不需要指定参数类型,默认多态
复制代码

 

复制代码
#封装
class E():
    def __init__(self):
        self.__test = 'T' # 双下划线定义为 私有变量; 注意类的外部不可以定义私有变量
        print('11111', test)#直接输出会输出对象
        self.test1 = 'T1'
        self.__test2()

    def __test2(self):# 私有方法
        print('TEST2')

    def test3(self):
        print(self.__test)

class F(E):
    def __init__(self):
        self.__test2()


e = E()
# print(e.__test)# 异常,私有变量在类外部不可用
print(e.__dict__) # 返回字典中有 _E__test 一个变量,其实是私有变量的名字
print(e._E__test) # T 可以强制访问到,但不推荐
print(e.test1)

#e.__test2()# 异常,私有类不能在外部使用
e.test3()

# f = F()# 异常,私有类不能继承,所以子类也不可用
复制代码

 

posted @   尐少  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示