初识面向对象

类:具有相同属性和技能的食物        语法:class   类名:   类名的首字母大写  例:class Person:

对象(实例):具体的某一事物;具体类的表现;具体的实实在在的一个实例

实例化:类---->对象的过程

例:

class Preson:
soup = "有灵魂"
language = "语言"
mind = "有思想"

def __init__(self, name, sex, age): #self:内存空间
self.name = name
self.sex = sex
self.age = age

def eat(self):
print("%s在吃饭" % self.name)

def sleep(self):
print("%s在睡觉" % self.name)

def work(self):
print("%s在工作" % self.name)

调用:

类名角度

1.调用类中的静态变量

方法一: 函数__dict__ 只能进行查找 不能进行增删改

例:

print(Preson.__dict__)
结果:{'__module__': '__main__', 'soup': '有灵魂', 'language': '语言', 'mind': '有思想', '__init__': <function Preson.__init__ at 0x000001E43FCD1A60>, 'eat': <function Preson.eat at 0x000001E43FCD1AE8>, 'sleep': <function Preson.sleep at 0x000001E43FCD1B70>, 'work': <function Preson.work at 0x000001E43FCD1BF8>, '__dict__': <attribute '__dict__' of 'Preson' objects>, '__weakref__': <attribute '__weakref__' of 'Preson' objects>, '__doc__': None}

例:

print(Preson.__dict__["soup"])  ==>有灵魂

方法二:  " . "  进行增删改查

例:

print(Preson.soup)
Preson.money = "运用货币"
Preson.language = "使用语言"
del Preson.soup
print(Preson.__dict__)
结果:有灵魂
{'__module__': '__main__', 'language': '使用语言', 'mind': '有思想', '__init__': <function Preson.__init__ at 0x000002194CF21A60>, 'eat': <function Preson.eat at 0x000002194CF21AE8>, 'sleep': <function Preson.sleep at 0x000002194CF21B70>, 'work': <function Preson.work at 0x000002194CF21BF8>, '__dict__': <attribute '__dict__' of 'Preson' objects>, '__weakref__': <attribute '__weakref__' of 'Preson' objects>, '__doc__': None, 'money': '运用货币'}

2.用类名调用类中的方法  基本不用

 

对象角度

1.对象操作类中的静态变量只能查

例:

print(p.soup)    ==>有灵魂

2.对象操作类中的方法   第一个参数self不用传

例:

p.work()    ==>小白在工作

 

实例化对象/实例/对象:

类名+()的过程叫实例化过程(创建一个对象的过程)

例:

p = Preson("小白", "男", 24)
print(p.__dict__)
结果:{'name': '小白', 'sex': '男', 'age': 24}

(1).类名+()产生一个实例(对象.对象空间)

(2).自动执行类中的__init__方法,将对象空间传给__init__的self参数

(3).给对象封装属性

__init__函数参数(属性)的增删改查

例:

p.height = 185     #增
del p.age #删
p.name = "小黑" #改
print(p.sex) #查
print(p.__dict__)
==>男
{'name': '小黑', 'sex': '男', 'height': 185}

  

查询顺序:

在执行类名()时产生一个含有类对象指针的空间

(1).对象>属性:先从对象空间找,如果找不到再从类空间找,再找不到再从父类找.

(2).类名>属性:先从本类空间找,如果找不到再从父类空间找

对象和对象之间是互相独立的

例:计算实例化的次数

class Preson:
count = 0
def __init__(self):
Preson.count = Preson.count + 1
obj1 = Preson()
obj2 = Preson()
obj3 = Preson()
print(Preson.count) ==>3

通过类名可以更改类中的静态变量值,但是通过对象不能改变,只能引用类中的静态变量

组合:给一个类的对象封装一个属性,这个属性是另一个类的对象

例:

class GameRole:
def __init__(self,name,ad,hp):
self.name = name
self.ad = ad
self.hp = hp
def attack(self,p):
p.hp = p.hp - self.ad
print("%s攻击了%s,%s掉了%s血,还剩%s血" % (self.name,p.name,p.name,self.ad,p.hp))
def armament_weapon(self,wea):
self.wea = wea

class Weapon:
def __init__(self,name,ad):
self.name = name
self.ad = ad
def fight(self,p1,p2):
p2.hp = p2.hp - self.ad - p1.ad
print("%s用来%s打了%s,%s掉了%s血,还剩%s血" % (p1.name,self.name,p2.name,p2.name,self.ad,p2.hp))
p1 = GameRole("灰太狼",20,500)
p2 = GameRole("红太狼",50,300)
w1 = Weapon("平底锅",70)
p2.armament_weapon(w1)
p2.wea.fight(p2,p1)
结果:红太狼用来平底锅打了灰太狼,灰太狼掉了70血,还剩380血

 

面向对象的三大特点:继承.多肽.封装

 

继承好处:

a:提高了代码的复用性
b:提高了代码的维护性
c:让类与类之间产生了关系,是多态的前提
 
初始继承:子类及子类实例化的对象,可以访问父类的所有方法和静态变量
 

例:子类既要执行子类的方法,又要执行父类的方法

class Animal:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
def eat(self):
print("%s吃东西" % self.name)
def drink(self):
print("喝水")
class Dog(Animal):
def action1(self):
print("会看门")
class Cat(Animal):
def action2(self):
print("会抓老鼠")
class Chicken(Animal):
pass
class Bird(Animal):
def __init__(self,name,sex,age,wing):
# Animal.__init__(self,name,sex,age)
super().__init__(name,sex,age)          #super只能在子类中使用
     # super(Bird,self).__init__(name,sex,age)
self.wing = wing
def eat(self):
super().eat()
print("%s吃虫子" % self.name)
d1 = Dog("小黑","女",5)
c1 = Cat("白白","女",2)
m1 = Chicken("小花","女",2)
c1.eat()
c1.action2()
b1 = Bird("鹦鹉","公",20,"花翅膀")
b1.eat()
结果:
白白吃东西
会抓老鼠
鹦鹉吃东西
鹦鹉吃虫子

多继承

类:经典类和新式类

经典类:不继承object函数的都是经典类 在python2所有的类都不继承object所有的类默认是经典类,可以添加object变成新式类  查询遵循:深度优先 

新式类:凡是继承object函数的都是新式类  在python3中所有的类都默认继承object.所有的类都是新式类  查询遵循:广度优先

例:

class A:
def fn(self):
print("in A")
class B(A):
def fn(self):
print("in B")
class C(A):
def fn(self):
print("in C")
class D(B):
def fn(self):
print("in D")
class E(C):
def fn(self):
print("in A")
class F(D,E):
def fn(self):
print("in A")
f1 = F()
f1.fn()
print(F.mro()) #查询类的继承顺序只适用于新式类

 

广度优先: 每个节点有且只走一次

                        

 

一路走到倒数第二级,判断 如果其它路能走到终点,则走另一条路, 如果走不到则接着走

 

深度优先:  一条路走到底

                    

 

多继承(C3)算法原理:

例:

class H:
def fn(self):
print("H fn")
class G(H):
def fn(self):
print("G fn")
class F(H):
def fn(self):
print("F fn")
class E(G):
def fn(self):
print("E fn")
class D(F):
def fn(self):
print("D fn")
class C(E):
def fn(self):
print("C fn")
class B(D):
def fn(self):
print("D fn")
class A(B,C,D):
def fn(self):
print("A fn")
a = A()
print(A.mro())
结果:[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.H'>, <class 'object'>]

 

接口类:

接口类和抽象类的定义:制定一个规范     思想:归一化接口设计

例:

class Alipay:
def __init__(self,money):
self.money = money
def pay(self):
print("使用支付宝支付%s" % self.money)
class Jdongpay:
def __init__(self,money):
self.money = money
def pay(self):
print("使用京东支付%s" % self.money)
def pay(obj):
obj.pay()
a1 = Alipay(200)
j1 = Jdongpay(100)
pay(a1)
pay(j1)
结果:
使用支付宝支付200
使用京东支付100

强制制定一个规范:凡是继承基类的子类中必须有...方法,如果没有实例化对象会报错

例:

from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self):pass       #每一个继承Payment类的子类必须含有pay方法
class Alipay(Payment):
def __init__(self,money):
self.money = money
def pay(self):
print("使用支付宝支付%s" % self.money)
def pay(a):
a.pay()
p1 = Alipay(200)
pay(p1) ==>使用支付宝支付200

 

多态 :

python没有多态概念,处处都是多态   

python没有多态,它有鸭子类型

鸭子类型:看着像鸭子,他就是鸭子 ------几个类中都含有相同的方法,互成为鸭子

例:

class Str:
def index(self):
pass
class List:
def index(self):
pass
class Tuple:
def index(self):
pass

 

封装:

广义的封装:实例化一个对象,给对象空间封装一些属性

狭义的封装:私有制

私有成员:私有静态属性,私有方法,私有对象属性,私有类方法,私有静态方法

例:

class Person:
mind = "有思想"
__soul = "灵魂" #私有静态变量
def __eat(self): #私有方法
print("吃饭")
def __init__(self,money): #私有属性
self.__money = money

类的外部(类名.实例化对象.子类)不能访问私有静态变量

类的内部可以访问

例:

class Person:
mind = "有思想"
__soul = "灵魂" #私有静态变量
def __eat(self): #私有方法
print(self.__soul)
print("吃饭")
def drink(self):
print("喝水")
def __init__(self,money): #私有属性
self.__money = money
p1 = Person(100)
p1.drink() ==>喝水
#类外部也可以访问
#print(Person._Person__soul) ==>灵魂

私有方法和私有属性的内部调用

例:

class Person:
mind = "有思想"
__soul = "灵魂" #私有静态变量
def __eat(self): #私有方法
print("吃饭")
def __init__(self,money): #私有属性
self.__money = money
def drink(self):
print("喝水")
self.__eat() #内部调用私有eat方法
def money(self):
print("花了%s块钱" % self.__money) #内部调用私有money属性
p1 = Person(100)
p1.drink() ==>喝水 吃饭
p1.money() ==>花了100块钱
print(Person._Person__soul)   #在类外面也可以调用私有方法但一般不用     ==>灵魂

例:

class Parent:
def __func(self):
print("in Parent func")
def __init__(self):
self.__func() <==> self._Parent__func()
class Son(Parent):
def __func(self):
print("in Son func")
son1 = Son() ==>in Parent func

 

伪装属性:

将一个方法伪装成一个属性,在代码的级别没有本质的提升,但是让其看起来更合理

 用在类似名词却需要计算的地方例如:BMI,面积,周长等

例:

class Heather:
def __init__(self,name,weight,height):
self.name = name
self.__weight = weight
self.__height = height
@property
def bmi(self):
BMI = round(self.__weight/self.__height**2,2)
print("%s的体脂数是%s" % (self.name,BMI))
p1 = Heather("小白",55,1.75)
p1.bmi ==>小白的体脂数是17.96

属性的改值:

例:

class Person:
def __init__(self,name,age):
self.name = name
self.__age = age
@property
def age(self): 方法名字要相同
return self.__age
@age.setter
def age(self,a1): 把要修改的值传给a1
print(a1)
p1 = Person("小白",24)
p1.age = 26
p1.age ==>26

例:判断年龄是不是整数 和 删除属性

class Person:
def __init__(self,name,age):
self.name = name
self.__age = age if type(age) is int else print("您输入的格式不正确")
@property
def age(self):
return self.__age
@age.setter
def age(self,a1):
self.__age = a1 if type(a1) is int else print("您输入的格式不正确!")
@age.deleter
def age(self):
del self.__age
p1 = Person("小白",19)
p1.age = 20
print(p1.age) ==>20
del p1.age
print(p1.__dict__) ==>{'name': '小白'}

三级运算:True:part if 条件判断 else False:part

 

类方法:

通过类名调用的方法,类方法中第一个参数约定俗称cls,python自动将类名(类空间)传给cls.

例:

class A:
def func(self):
print(self)
@classmethod
def func1(cls):
print(cls)
a1 = A()
print(a1.func)
print(A.func1)
a1 = A()
a1.func1() 对象调用类方法,传给cls参数也是该对象的所属类,cls得到的是类本身
结果:
<bound method A.func of <__main__.A object at 0x000001D7362BFF28>>
<bound method A.func1 of <class '__main__.A'>>
<class '__main__.A'>

类方法的应用:

(1).类中有些方法是不需要传入对象,不要对象的一切东西(不需要对象的参与)

例:

class Person:
name = "小白"
count = 1
@classmethod
def func(cls):
return cls.name+str(cls.count+1)
print(Person.func()) ==>小白2

(2).对类中的静态变量进行改变要用类方法

(3).在继承中父类得到子类的类空间

例:

class A:
age = 19
@classmethod #类方法---对子(B)类中的所有内容都可以进行访问和修改
def func(cls):
print(cls)
def func1(self): #方法--只能访问子(B)类中的所有内容
print(self)
class B(A):
age = 22
B.func()        ==><class '__main__.B'>

 

静态方法:

例:

class A:
@staticmethod
def func():
print("123")
A.func() ==>123

静态方法的优点:

(1).代码块清晰

(2)复用性,减少代码量

 

posted @ 2018-07-23 18:55  烟灰与黑  阅读(123)  评论(0编辑  收藏  举报