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()# 异常,私有类不能继承,所以子类也不可用