一种柑、什么是對(duì)象和類
1. 從現(xiàn)實(shí)世界說起
什么是對(duì)象
現(xiàn)實(shí)世界中岗仑,任何一個(gè)可見,可觸及的物體都可以成為對(duì)象聚请。
比如說一輛汽車荠雕,一個(gè)人,都可以稱為對(duì)象驶赏。
那每個(gè)對(duì)象都是有屬性和功能(或者說技能)的炸卑。
比如:
一輛汽車的屬性有:
- 重量
- 具體的大小尺寸
- 車身顏色
- 價(jià)格
一輛汽車的功能有:
- 行駛
- 載人
什么是類
什么又是類呢?
聽人們常說煤傍,物以類聚盖文,人以群分。
從字里行間不難看出蚯姆,類就是具體很多對(duì)象共有屬性和共有功能的抽象體五续。
這個(gè)抽象體,只是一個(gè)稱謂龄恋,代表了具有相同屬性和功能的某些對(duì)象疙驾。
比如,具體的一輛汽車是一個(gè)對(duì)象篙挽,紅色汽車就是這些具有紅色車身的汽車的統(tǒng)稱荆萤,紅色汽車就是一個(gè)類了。
相關(guān)的例子還有很多铣卡,比如 蔬菜是一個(gè)類链韭,一個(gè)具體的茄子是屬于蔬菜這個(gè)類的。
現(xiàn)實(shí)世界中是先有對(duì)象后有類的煮落。
2. 回到計(jì)算機(jī)的世界
在計(jì)算機(jī)的代碼中要表示對(duì)象的屬性就是使用變量名 和數(shù)據(jù)的綁定方式敞峭。
如 color = 'red'
那要表示對(duì)象的功能(或者說技能),在計(jì)算機(jī)的代碼中是用函數(shù)實(shí)現(xiàn)的蝉仇。這里的函數(shù)會(huì)被稱為對(duì)象的 方法
計(jì)算機(jī)世界中是先有類旋讹,后有對(duì)象的。
就像建造一棟樓房轿衔,需要先有圖紙沉迹,之后按照這個(gè)圖紙建造房子。
在計(jì)算機(jī)語言中害驹,都是先創(chuàng)建一個(gè)類鞭呕,給這個(gè)類定義一些屬性和方法。之后通過這個(gè)類去實(shí)例化出一個(gè)又一個(gè)的對(duì)象宛官。
3. 什么是面向?qū)ο蟮木幊?/h2>
先說編程葫松,個(gè)人理解瓦糕,編程就是利用編程語言書寫代碼邏輯,來描述一些事件腋么,在這個(gè)過程中會(huì)涉及到具體對(duì)象咕娄,具體的條件約束,以及事件的結(jié)果珊擂。
比如圣勒,現(xiàn)實(shí)世界中的一件事,鯊魚學(xué)開車未玻。
鯊魚是我的網(wǎng)名
^_^
這里涉及到的對(duì)象有
- 車
- 教練
- 鯊魚
- 道路
涉及到的技能有
- 車 :
- 行駛
- 教練 :
- 開車
- 教學(xué)員學(xué)開車
- 鯊魚:
- 學(xué)習(xí)開車
當(dāng)然所涉及到的東西灾而,不止上面的這些,這里只是簡(jiǎn)單舉例扳剿,表明原理即可旁趟。
假如想表述鯊魚學(xué)開車這件事。
鯊魚跟著教練學(xué)習(xí)開車技能庇绽,使用的是綠色吉普汽車锡搜,之后他學(xué)會(huì)了開車。
很簡(jiǎn)單是吧瞧掺,但是耕餐,要在計(jì)算機(jī)中體現(xiàn)出來該怎么辦呢?
1 先定義每個(gè)對(duì)象的類辟狈,在類里定義各自對(duì)象的屬性和方法
2 通過類把對(duì)象創(chuàng)建處來肠缔,這個(gè)創(chuàng)建的過程成為實(shí)例化,實(shí)例化的結(jié)果成為這個(gè)類的一個(gè)實(shí)例哼转,當(dāng)然這個(gè)實(shí)例也是一個(gè)對(duì)象明未,一切皆對(duì)象嘛。
3 利用實(shí)例的方法互相作用得到事件單結(jié)果壹蔓。
從最后一條不難發(fā)現(xiàn)趟妥, 每個(gè)對(duì)象的方法可以和其他對(duì)象進(jìn)行交換作用的,從而也產(chǎn)生了新的結(jié)果佣蓉。
這種用對(duì)象的方法和屬性去相互作用來編寫代碼的邏輯思維或者說是編寫代碼的風(fēng)格就是面向?qū)ο蟮木幊塘恕?/p>
面向?qū)ο缶幊?Object Oriented Programming 簡(jiǎn)稱 OOP披摄,是一種程序設(shè)計(jì)思想。
OOP把對(duì)象作為程序的基本單元勇凭,一個(gè)對(duì)象包含了數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)疚膊。
面向?qū)ο蟮某绦蛟O(shè)計(jì)是把計(jì)算機(jī)程序視為一組對(duì)象的集合,而且每個(gè)對(duì)象都可以接收其他對(duì)象發(fā)過來的消息虾标,并處理這些消息酿联,計(jì)算機(jī)程序的執(zhí)行就是一系列消息在各個(gè)對(duì)象之間傳遞。這就是對(duì)象之間的交互夺巩。
二贞让、Python 中一切皆對(duì)象
你可能聽說過,在 Python 中一切皆對(duì)象柳譬。
在python中喳张,一切皆對(duì)象。數(shù)字美澳、字符串销部、元組、列表制跟、字典舅桩、函數(shù)、方法雨膨、類擂涛、模塊等等都是對(duì)象,包括你的代碼聊记。
之前也提到過撒妈,Python 中的對(duì)象都有三個(gè)特性
id
標(biāo)識(shí)了一個(gè)對(duì)象的唯一性,使用內(nèi)置函數(shù)id()
可以獲取到類型
表明了這個(gè)對(duì)象是屬于哪個(gè)類排监, 使用內(nèi)置函數(shù)type()
可以獲取到值
就是這個(gè)對(duì)象的本身狰右,可以使用內(nèi)置函數(shù)print()
看到,這個(gè)看到的是 Python 讓你看到的一個(gè)對(duì)象特有的表現(xiàn)方式而已舆床。
三棋蚌、創(chuàng)建類
使用關(guān)鍵字 class
創(chuàng)建一個(gè)類。
類名其實(shí)和之前我們說的使用變量名的規(guī)則一樣挨队。
但是這里有一點(diǎn)兒要注意谷暮,就是類名的第一個(gè)字母需要大寫,這是規(guī)范瞒瘸。
class Foo:
pass
class Car():
color = 'red' # 屬性
def run(self): # 方法
pass
四坷备、實(shí)例化對(duì)象
使用 類名()
可以實(shí)例化一個(gè)對(duì)象,你可以使用給這個(gè)實(shí)例化的對(duì)象起一個(gè)名字情臭。
定義類
class Car():
color = 'red' # 屬性
def travel(self): # 方法
pass
實(shí)例化一個(gè)對(duì)象
Car() # 沒有起名字
mycar = Car() # 起了個(gè)名字 mycar
由類實(shí)例化出的對(duì)象成為這個(gè)類的一個(gè)實(shí)例
五省撑、屬性
類的屬性分為類的數(shù)據(jù)屬性(key=value)和函數(shù)屬性
類的實(shí)例只有數(shù)據(jù)屬性(key=value)
class Person():
city = "BeiJing" # 類的數(shù)據(jù)屬性
def __init__(self, name,age):
self.name = name # 實(shí)例對(duì)象的數(shù)據(jù)屬性
self.age = age
def run(self): # 類的函數(shù)屬性
pass
類屬性可以被類和對(duì)象調(diào)用, 是所有對(duì)象共享的
實(shí)例屬性只能由對(duì)象調(diào)用
六、對(duì)象的初始化方法 __init__()
對(duì)象的初始化方法是用于實(shí)例化對(duì)象時(shí)使用的俯在。
方法的名稱是固定的 __init__()
當(dāng)進(jìn)行實(shí)例化的時(shí)候竟秫,此方法就會(huì)自動(dòng)被調(diào)用。
# coding:utf-8
# auther shark
# 2019/5/7 09:14
class AP():
area = '藍(lán)方' # 類的屬性 -- 類的數(shù)據(jù)屬性
def __init__(self, name, hp=690, atc=78): # 類的函數(shù)屬性
self.name = name # 對(duì)象的屬性
self.hp = hp
self.atc = atc
zj = AP("甄姬")
xq = AP("小喬")
# print(zj.name)
# print(zj.hp)
# print(zj.atc)
#
# print(zj.area)
# print(xq.area)
#
#
# print(AP.area)
# print(AP.__dict__)
# # print(AP.name)
#
# print(zj.__dict__)
# print(xq.__dict__)
# print(xq.__dict__.get('name'))
# print(type(xq))
# print(type('hello'))
#
#
# print(isinstance(xq, AP))
# print(isinstance('hello', str))
#
# # 工廠函數(shù)
# li = list()
# print(isinstance(li, list))
七跷乐、方法
凡是在類里定義的函數(shù)都都稱為方法
方法本質(zhì)上是函數(shù)肥败,也是類的函數(shù)屬性
class AP:
# 實(shí)例的綁定方法 類的函數(shù)屬性
def __init__(self, name, hp=690, atc=78):
self.name = name # 對(duì)象的屬性
self.hp = hp
self.atc = atc
def run(self): # 對(duì)象的方法
print(self, id(self))
print("{} is running".format(self.name))
zj = AP("甄姬")
xq = AP("小喬", hp=780)
# print(id(zj))
# zj.run()
print(id(xq))
xq.run()
方法可以被這個(gè)類的每個(gè)實(shí)例對(duì)象調(diào)用,當(dāng)一個(gè)實(shí)例對(duì)象調(diào)用此方法的時(shí)候, self
會(huì)被自動(dòng)傳值馒稍,傳入的值就是目前調(diào)用此方法的 實(shí)例對(duì)象皿哨。
八、魔方方法 __str__()
實(shí)現(xiàn)定義類的實(shí)例的表現(xiàn)形式
當(dāng)我們定義一個(gè)類的時(shí)候纽谒,默認(rèn)打印出它實(shí)例時(shí)是不易讀的证膨,某些情況下我需要讓這個(gè)類的實(shí)例的表現(xiàn)形式更易讀。就可以使用 __str__()
這個(gè)方法鼓黔。
使用前
class Person:
def __init__(self, name):
self.name = name
p = Person('shark')
print(p)
# <__main__.Person object at 0x10ac290f0>
使用后
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return "{}".format(self.name)
p = Person('shark')
print(p)
# shark
其實(shí)央勒,
__str__()
方法本身在我們定義類的時(shí)候就已經(jīng)存在了,是 Python 內(nèi)置的澳化。我們?cè)谶@里只是有把這個(gè)方法重寫了崔步。
這個(gè)方法在使用的時(shí)候有返回值
,且返回值必須是字符串
類型
九缎谷、繼承
在現(xiàn)實(shí)世界中井濒,類的繼承,表現(xiàn)為我們可以把一個(gè)類的共同的屬性和方法再進(jìn)行一個(gè)高度的抽象慎陵,成為另一個(gè)類眼虱,這個(gè)被抽象出來的類成為父類,剛才被抽象的類成為子類席纽。
但在計(jì)算機(jī)中捏悬,需要先定義一個(gè)父類,之后再定義其他的類(子類)并且繼承父類润梯。
這時(shí)子類即使什么也不用做过牙,就會(huì)具備父類的所以屬性(數(shù)據(jù)屬性和函數(shù)屬性)。這在計(jì)算機(jī)語言中就被稱為繼承
纺铭。 繼承并不是 Python 語言特有的寇钉,而是所有面向?qū)ο笳Z言都有的特性。
面向?qū)ο笳Z言的特性還有另外兩個(gè): 多態(tài)
, 封裝
舶赔。
繼承
扫倡、 多態(tài)
和 封裝
被稱為面向?qū)ο笳Z言都三大特性。
這里我們先只對(duì) 繼承
來講解竟纳。
1. 單純的繼承
下面我是定義了兩個(gè)類 Person
和 Teacher
撵溃。
Teacher
繼承了 Person
Teacher
被稱為子類, Person
就是父類
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
print(f'{self.name} is running')
class Teacher(Person):
pass
t = Teacher('shark', '18')
t.run()