面向對象進階

面向對象的三大特性:  ①繼承  ②封裝  ③多態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)
獲得結果  對象地址都是同樣的
相關文章
相關標籤/搜索