1. 程式人生 > >綁定與非綁定方法 繼承 繼承與抽象 查找屬性關系 派生與覆蓋 訪問父類的內容

綁定與非綁定方法 繼承 繼承與抽象 查找屬性關系 派生與覆蓋 訪問父類的內容

__init__ 名稱空間 self. 問題 修改 people sel 人的 bsp

類屬性與對象屬性

類中應該僅存儲所有對象共有的內容
 如所有人的國籍相同那就放到類中

對象中存儲每個對象獨有的內容
?  如每個人的名字都不同


初始化函數
class Person:
    color = ‘white‘
def read(self):
print(‘hamlet‘)

# 創建對象 也稱之為實例化 產生的對象也稱之為實例
a1=Person()
print(a1)
print(a1.color)
print(a1.__dict__)

a2 = Person()
print(a2)
print(a2.read())
print(a2.__dict__)

print(id(a1.color))
print(id(a2.color))
print(id(Person.color))

# 當修改某一個對象的屬性時 ,不會影響其他對象和類

a2.color = ‘black‘
print(a2.color)
print(a1.color)
print(Person.color)


# 類中應該僅存儲所有對象都相同的內容
# 如果每個對象的屬性都不同則應該放到對象自己的名稱空間中
# 如一個班級中所有學員的老師都相同


# 對象中存儲每個對象獨有的內容
# 如每個人的名字都不同
例子
class Person:
people = ‘mingren‘

def student(self):
print(‘正在練習‘)

peo1 = Person()
# print(peo1)
peo1.name=‘索隆‘
peo1.height=185

peo2 =Person()
peo2.name = ‘路飛‘
peo2.height =180

# 封裝一個方法來初始化對象的屬性
def my__init(peo,name,height):
peo.name=name
peo.height=height

peo1=Person()
peo2=Person()

my__init(peo1,‘索隆‘,185)
my__init(peo2,‘路飛‘,180)

print(peo1.name)
print(peo1.height)
print(peo2.name)
print(peo2.height)

# __init__方法的使用
# init 是初始化的縮寫 用於為對象的屬性設置初始值
# 特點
# 執行時機:當實例化產生對象時會自動執行該函數
# 會自動傳入需要初始化的對象
# 初始化必須包含至少一個參數 用於表示對象本身
# 該函數不允許有返回值 必須為None

class Cat:
def __init__(self,age,name,**kwargs):
# print(self)
self.age=age
self.name=name

a1=Cat(1,‘花花‘)
a2=Cat(2,‘草草‘)

print(a1.name)
print(a2.name)


綁定方法
class Person:

def __init__(self,name,age):
self.name=name
self.age=age
# 默認情況下 在類中定義的方法 都是綁定方法
def say_hio(self):
print(‘i am %s‘% self.name)

# 當你創建對象時 發生什麽
# 1.產生一個空對象 (名稱空間)
# 2.自動調用__init__方法 並且把這個對象以及額外的參數傳入
a1=Person(‘山治‘,19)
a1.say_hio()
a2=Person(‘娜美‘,18)
a2.say_hio()
綁定方法
class Person:

def __init__(self,name,age):
self.name=name
self.age=age
# 默認情況下 在類中定義的方法 都是綁定方法
def say_hio(self):
print(‘i am %s‘% self.name)

# 當你創建對象時 發生什麽
# 1.產生一個空對象 (名稱空間)
# 2.自動調用__init__方法 並且把這個對象以及額外的參數傳入
a1=Person(‘山治‘,19)
a1.say_hio()
a2=Person(‘娜美‘,18)
a2.say_hio()

# 經常使用的數據定義為變量

username=‘josn‘
pwd=‘1234‘
db_name=‘wechat‘


atm_user=‘rosc‘

atm_pwd=‘14778‘
#用於登錄數據庫
def login_data_base(username,pwd,db_name):
print(‘%s登錄%s數據庫 密碼為%s‘%(username,db_name,pwd))

def login_atm(username,pwd):
print(‘%s登錄了ATM 密碼為%s‘%(username,pwd))


login_data_base(username,pwd,db_name)
login_atm(atm_user,atm_pwd)

# login_data_base("rose","321","weix")
#綁定的好處是
#將數據以及處理數據的方法綁定在一起
#拿到對象就同時拿到數據和處理的方法
#直接調用即可

# 可以這麽理解 :
# 面向對象其實就是提高整合程度
# 把數據和方法整合到一起
綁定方法與普通函數的區別

當使用類調用時,就是一個普通函數 有幾個參數就得傳幾個參數

當用對象來調用時,是一個綁定方法了,會自動將對象作為第一個參數傳入
綁定方法與非綁定方法
一個類中可以有屬性和方法

方法分為兩種

1.綁定方法

? 1對象綁定方法

? 在使用對象調用時會自動傳入對象本身

? 2類綁定方法

? @classmethod

? 在使用對象調用時會自動傳入類本身

? 在使用類來調用時也會自動傳入類本身

? 單例模式中就會經常使用@classmethod
類的函數屬性是綁定給對象使用的,obj.method稱為綁定方法,內存地址都不一樣



到底綁定給誰?

當你的方法執行過程中需要使用到對象中數據時就綁定給對象

當你的方法執行過程中需要使用到類中數據時就綁定給類



2.非綁定方法

即不需要對象中的數據 也不需要類中的數據 那就定義為非綁定方法,就是普通函數

@staticmethod
class Student:

school=‘hanghai‘
def __init__(self,name):
self.name=name

# 默認情況下是綁定方法
def study(self):
print(self)
# 對於類而言study就是普通函數
# 而對於對象而言 他是一個綁定方法 當使用對象來調用時 會自動將對象作為第一個參數傳入
import time
class Person:

country = ‘china‘
def __init__(self,name,age):
self.name=name
self.age=age

@classmethod
def info(cls):
print(cls)
print(‘info go‘)

def say_no(self):
print(‘no good %s‘%self.name)


# q=Person(‘rose‘,20)
# q.info()
# print(Person)
# print(Person.info)
# Person.info()
# p = Person("rose",10)
# p.say_no()

# 是要輸出這個類的一些信息

@classmethod
def class_info(cls):
print(‘the class %s is module xxx.py‘%cls.__info__)
# 輸出當前時間
# 不需要訪問類也不需要訪問對象 所以直接做成非綁定方法

@staticmethod
def show_time(self):
print(time.localtime())


q=Person(‘rosc‘,1)
q.show_time(1)

繼承:

繼承是一種創建新類的方式,新建的類可以繼承一個或多個父類(python支持多繼承),父類又可稱為基類或超類,新建的類稱為派生類或子類。

子類會“”遺傳”父類的屬性,從而解決代碼重用問題


在OOP中 繼承描述是類和類之間的關系 例如b類繼承a類 b類可以直接使用a類中的屬性和方法

a是父類(基類,超類) b是子類(派生類)

好處:極大的提高了代碼的復用性
如何使用繼承,至少需要兩個類

語法:

class 子類名稱(父類名稱):

? pass

抽象與繼承

繼承之後可以直接使用父類的屬性和方法

使用繼承時 應該先抽象 在繼承

抽象指的是 將一系列類中相同的特征和相同行為抽取 形成一個新的類

會產生一些與原本業務不想關的類

站在不同角度會得到不同的抽象結果

![抽象過程](C:\Users\dell\Desktop\抽象過程.png)

繼承:是基於抽象的結果,通過編程語言去實現它,肯定是先經歷抽象這個過程,才能通過繼承的方式去表達出抽象的結構。

例子
class OLDBIOYPerson:
school=‘oldboy‘
def __init__(self,name,age):
self.name=name
self.age=age

def say_no(self):
print(‘hello %s‘%self.name)

class Teacher(OLDBIOYPerson):
def teach(self):
print(‘正在備案...‘)

class Student(OLDBIOYPerson):
pass

# 測試
a=Teacher(‘ice‘,26)
a.say_no()
a.teach()

w=Student(‘paper‘,24)
w.say_no()
--不重要
__base__只查看從左到右繼承的第一個子類,__bases__則是查看所有繼承的父類
class ParentClass1:
pass

class ParentClass2:
pass

class SubClass1(ParentClass1):
pass

class SubClass2(ParentClass1,ParentClass2):
pass
# __base__只查看從左到右繼承的第一個子類,
# __bases__則是查看所有繼承的父類
print(SubClass1.__bases__)

print(SubClass2.__bases__)

print(SubClass2.__base__)


# 一切皆對象指的是 
# 在python3中任何類都直接或間接繼承自Object

# Object是所有類的基類 (根類)

# 其中提供一系列方法, 這樣一來 無論你是什麽類 ,你都可以直接是object中已經存在的方法
# 一切皆對象

在python中您所使用到的任何數據都是對象 int float list dict 模塊 包
class Test:
pass

a = 10
print(type(a))

li = []
print(type(li))

t = Test()
print(type(t))

查找順序
class A:
name=‘ham‘
# def __str__(self):
# print(‘111111‘)
# pass
pass

class B(A):
name =‘rose‘
pass

b=B()
b.name=‘aaa‘

print(b.__str__())

# 查找順序
# 對象自己 - > 所在的類 -> 所在類的父類 -> 父類的父類 -> object

派生與覆蓋

‘‘‘派生
當一個類繼承自另一個類 並且這個子類擁有與父類不同的內容 就稱之為派生
‘‘‘
class A:
def info(self):
print(‘hello world‘)
class B:
pass


‘‘‘
覆蓋 (重寫)
子類中出現了與父類名稱相同的屬性 或方法 就會覆蓋掉父類的屬性或方法
‘‘‘
class A:
text=‘124‘
def info(self):
print(‘hello‘)

class B(A):
text=‘529‘
def info(self):
print(‘hello,asedrk‘)
pass

b=B()
b.info()
print(b.text)
訪問父類的內容
class Person:
text=‘147‘
def __init__(self,name,age,):
self.name=name
self.age=age

def sleep(self):
print(‘吃飯,睡覺,打豆豆‘)
def say_no(self):
print(‘name:%s,age:%s‘%(self.name,self.age),end=‘‘)

class Student(Person):
text=‘852‘

# 由於父類已經存在一個方法可以完成這個三參數的初始化
# 所以可以直接調用父類的初始化完成這部分的初始化工作

def __init__(self,name ,age,number):
# [1]指名道姓的調用
Person.__init__(self,name,age)
# [2]super()
super().__init__(name,age)

# py2的寫法
# super(Student, self).__init__(name,age,gender)

self.number=number

# 訪問父類的屬性
def show_text(self):
print(self.text)
print(super().text)

def say_hi(self):
super().say_hi()
print("my number: %s" % self.number)

s = Student("jack",20,"man",)
s.say_no()
# 當你使用super()函數時,
# Python會在MRO列表上繼續搜索下一個類。
# 只要每個重定義的方法統一使用super()並只調用它一次
# ,那麽控制流最終會遍歷完整個MRO列表,
# 每個方法也只會被調用一次(
# 註意註意註意:使用super調用的所有屬性,
# 都是從MRO列表當前的位置往後找,
# 千萬不要通過看代碼去找繼承關系,一定要看MRO列表)




綁定與非綁定方法 繼承 繼承與抽象 查找屬性關系 派生與覆蓋 訪問父類的內容