面向对象的三大特性: ①继承 ②封装 ③多态java
简述面向对象的三大特性分别是什么,以及主要功能
# 封装、继承、多态。
# 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式;
# 继承:子类自动共享父类数据结构和方法的机制。单继承、多继承;
# 多态:多态是指相同的操做或函数、过程可做用于多种类型的对象上,并得到不一样的结果。
# 不一样的对象,收到同一消息能够产生不一样的结果,这种现象称为多态性;
继承:python
新式类: 继承object类的类就是新式类.(python3x中都是新式类)c#
经典类:不继承object类就是经典类.设计模式
python2x:默认全部类都不继承(object),这样就是新式类微信
继承又分为单继承和多继承.数据结构
单继承:函数
①查询顺序微信支付
class A:spa
name = 'alex'设计
def func(self)
print(666)
class B(A):
age = 12
b1 = B()
b1.age
b1.name
②既要执行父类的又执行子类的方法
class A:
name = 'alex'
def func(self):
print('IN A')
class B(A):
age = 12
def func(self):
#super().func() #第一种 super(B,self).func()
A,func(self) #第二种
print('IN B')
b1 = B()
b1.func()
# class A: # name = 'alex' # def func(self): # #self = self = b1 # print(self) # 1,a1地址 5 b1 地址 (分歧:a1 地址) 1,<__main__.A object at 0x0000000000711198> 5, <__main__.B object at 0x00000000007111D0> # print('IN A') # 2 IN A 6 IN A 2 IN A # # class B(A): # age = 12 # def func(self): # #self = b1 # super().func() # 第一种 super(B,self).func() # print(self) # 4,b1 地址 4 <__main__.B object at 0x00000000007111D0> # # A.func(self) # 第二种 # print('IN B') # 7 IN B # a1 = A() # a1.func() # print(a1) # 3 a1地址 <__main__.A object at 0x0000000000711198> # b1 = B() # b1.func() # print(b1) # b1 地址
多继承:
多继承分为 新式类和经典类
新式类:广度优先. python3x 类名.mro()
经典类:一直找,找到底
接口类,抽象类:
是在工做中书写的一种规范
强制制定规范,若是未按照规范执行,就会报错
from abc import ABCMeta,abstractmethod ##引入来自abc文件的 ABCmeta ,abstractmethod 两个模块
class Payment(metaclass=ABCMeta): # 抽象类 接口类 规范和约束 metaclass指定的是一个元类
@abstractmethod
def pay(self):pass # 抽象方法
class QQ(Payment):
def pay(self,money):
print('您用qq支付了%s元' % money)
def ret(self):
print('支付失败....')
class Ali(Payment):
def pay(self,money):
print('您用支付宝支付了%s元' % money)
class Wechat(Payment):
def pay(self,money):
print('您用微信支付了%s元' % money)
def pay(obj,money):
obj.pay(money) # a1.pay(200)
q1 = QQ()
a1 = Ali()
w1 = Wechat()
# q1 = QQ()
# a1 = Ali()
# pay(q1,100) # 统一化设计
# pay(a1,200)
# w1 = Wechat()
# pay(w1,500)
用处:在工做中,若是你要是规定几个类必须有同样的方法,
你要抽象类,制定一个规范,强制其有此方法
python没有多态的概念,可是python崇尚鸭子类型.
定义变量的方法:
1.java c# 须要定义 类型.
2.java c# 没有多继承的概念
鸭子类型:它看着像鸭子,那么它就是鸭子.↓
好比: str list tuple
str.index()
s1 = 'alex'
class Str:
def index(self):
pass
class List:
def index(self):
pass
class Tuple:
def index(self):
pass
python 中好多不一样类但同名的方法不是强制规定,而是约定俗成,像上面这三种类,都一样具备index方法,并且功能
类似,则,他们三个互为鸭子.
封装就是将一些属性或者方法(有用的信息)放置在一个空间中.
1,封装 对象的封装
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person('oldboy',1000)
p2 = Person('alex',10000)
print(p1.name)
print(p2.name)
2.封装(私有成员)
类的结构分析:
class Person:
mind = '有思想' ##第一部分:全部的共有静态变量,公有静态字段
__level = '高等动物' ##第一部分: (前面两个下划线) 私有静态变量,私有静态字段
def __init__(self,name,age,sex): ##构造方法 #第二部分: 动态方法,方法(函数)
self.name = name ##公有对象属性
self.age = age
self.__sex = sex ##私有对象属性
def func(self): ##第二部分:普通方法
print(666)
def __func1(self): ##第二部分:私有方法
print(777)
@staticmethod #静态方法
def f2():pass
@classmethod #类方法
def f2():pass
@property #属性
def hex(self):pass
总结:对于私有成员来讲,他加载到内存时,都会加上_类名__变量名,因此你在类的外部,或者派生类中都不可访问.
为何设置私有成员?
有些变量,方法,属性,只在类内部进行使用便可,不便于(不容许)类外部或者派生类去调用
isinstance(obj1,A) ##判断obj1是否是A实例化出来的, 判断这个对象是本类实例化的,或者是此类的子类实例化出来的
issubclass(B,A) ## 判断B是否是A的子类, 判断一个类是否是另外一个类的派生类
# *** item
# class Foo:
# def __init__(self, name, age, sex):
# self.name = name
# self.age = age
# self.sex = sex
# def __getitem__(self, item):
# # print(self.__dict__[item])
# # if hasattr(self,item):
# # return getattr(self,item)
# # else:
# # return '没有此属性'
# return getattr(self, item, '没有此属性')
# #
# def __setitem__(self, key, value):
# print(key,value)
#
# #
# def __delitem__(self, key):
# print(key)
# def __delattr__(self, item):
# print(item)
# print('del obj.key时,我执行')
#
#
#
# f1 = Foo('alex', 12, '男')
# print(f1['name']) # 对一个对象使用f1['name1']这种方法,自动触发__getitem__这个方法,将'oldboy123' 传到这个方法中.
# print(f1['age1'])
# f1['name1'] = 'wusir666' #对一个对象使用这种方法,自动触发 __setitem__
# del f1['fkjdslfjdslafj'] ##这个自动触发 __delitem__
# 若是你对对象进行类似的字典的操做,就会主动触发类中__getitem__ __setitem__ delitem__
# del f1.name
# del f1.aaaaaa
特殊方法::
__len__
class A:
def __init__(self,name,age):
self.name = name
self.age = age
def __len__(self):
return len(self.__dict__)
a1 = A('oldboy',1000)
print(len(a1))
# 若是对一个对象进行len()操做,
# 他会找到对象从属于的类中的__len__方法,而且此方法中必需要有数字的返回值.
__call__
对象后面加括号,触发执行.
注:构造方法的执行是由建立对象触发的,即:对象 = 类名();而对于__call__方法的执行是由对象后加括号()触发的,即:对象()或者 类()
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
__eq__
对一个类实例化的两个对象进行比较运算时,他会自动触发
# class A:
# def __init__(self):
# self.a = 1
# self.b = 2
#
# def __eq__(self,obj):
# if self.a == obj.a and self.b == obj.b:
# return True
# a1 = A()
# b1 = A()
# print(a1 == b1) # 对一个类实例化的两个对象进行比较运算的时候,他会自动触发类中的__eq__
__del__ 析构方法
在看析构以前 须要知道 python垃圾回收机制
python垃圾回收机制:文件中你建立的全部的变量,类等等,执行完毕以后,一段时间内若是没有用到,他会自动在内存中去除,
深刻研究:他会将你的全部变量,类等等作个标记,在一段时间以内,没有被调用,则就会自动回收.
析构方法:
class A:
def __init__(self):
pass
def __del__(self):
print(666)
al = A() ###这就触发了, 日了.
__new__
object 产生并返回一个对象空间.
本身定义的 __new__ 第一个参数自动接收类空间
执行顺序::先执行 __new__方法,而后在执行__init__方法
# class A:
# def __init__(self):
# self.x = 1
# print('in init function ')
#
# def __new__(cls, *args, **kwargs):
# print(cls) # <class '__main__.A'>
# print('in new function ')
# # return object.__new__(cls) # 调用object类中的__new__方法,产生一个真正的对象空间
# return super().__new__(cls) # 返回给 A()
# object
# a1 = A()
# print(a1)
# print(a1)
类名() 自动执行类中__new__ 类中没有,则找到object
找到__new__ 这个方法是产生一个对象空间,自动执行类中的__init__,给这对象空间封装一些属性,
最后返回给A() 而后给 变量a1
class A1:
def __new__(cls, *args, **kwargs):
'产生对象空间'
pass
class B(A1):
def __init__(self):
self.x = 1
def __new__(cls, *args, **kwargs):
print('B1')
b1 = B()
print(b1)
1,类名() 执行 __new__方法,先从本身的类中寻找,
若是没有找到,则从父类(直到object类)寻找,而后从object的__new__产生一个对象空间,返回给类名().
2,对象空间一旦产生并返回.则自动执行__init__方法,给这个对象空间封装属性.
3,最终你获得是封装好属性的对象空间.
设计模式 :单例模式,最简单的设计模式, (面常)
单例模式 :对一个类是能实例化一个对象
class A:
__instance = None
def __new__(cls, *args, **kwargs):
if A.__instance is None: # 第一次进入,知足这个条件
obj = object.__new__(cls) # 利用object 建立一个对象空间 给了obj
A.__instance = obj # 我将类的私有静态字段 __instance 从新赋值了 对象空间obj
return A.__instance
a1 = A()
b1 = A()
c1 = A()
print(a1,b1,c1)
获得结果 对象地址都是同样的