1.面向对象
面向对象是一种编程思想,即按照真实世界的思维方式构建软件上系统。
2.定义类
class 类名 [ (父类) ]:
类体
# coding = utf-8
class Car(obeject):
#类体
pass
#pass主要保持代码的完整性
3.创建对象
class Car(obeject):
#类体
pass
car = Car() #创建一个对象
4.类的成员
实例和类的区别:
实例是个体的,类是共有的变量
1…实例变量
实例变量就是对象个体特有的“数据”
例如:狗狗的名称和年龄
class Dog:
def _init_(self,name,age)
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
dog = Dog('老六',2)
print('这条狗叫{0}, {1}岁了'.format(d.name, d.age))
2…构造方法
类中的__init__()方法是一个非常特殊的方法,用来创建和初始化实例变量,这种方法就是 “构造方法”;由init 前后两个下划线构建方法。
class Dog:
def __init__(self,name,age, sex = '雌性')
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
self.age = sex
dog1 = Dog('老六',2)
dog2 = Dog('老八',1, '雄性')
dog3 = Dog(name = '哈哈',sex='雄性', age = 2)
print('这条狗叫{0}, {1}岁了'.format(d1.name, d1.age, d1.sex))
print('这条狗叫{0}, {1}岁了'.format(d2.name, d2.age, d2.sex))
print('这条狗叫{0}, {1}岁了'.format(d3.name, d3.age, d3.sex))
self 代表的是当前对象 数据个体的一个对象
self 调用方法时候不需要传递
构造方法实际为定义在类中的函数,采用类名的调用。
3. 实例方法
实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法。
class Dog:
#构造方法
def __init__(self,name,age, sex = '雌性')
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
self.age = sex
#实例方法
def run(self):
print ("{}在跑...".format (self.name))
#实例方法
def run(self):
print ('{}在叫,"{}"!'.format (self.name,sound))
dog = Dog('老八',2)
dog.run
dog.speak('嘿嘿嘿~')
def run(self)# 实例方法就是将当前方法绑定到实例上
4. 类变量
类变量是属类的变量, 不属于单个对象
class Account:
interest_rate = 0.0568 #类变量 利率interest_rate
#构造方法
def __init__(self,owner,amuont):
self.owner = owner #创建并初始化实例变量owner
self.amount = amount
account = Account ('tony', 6655655.0)
print('账户名:{0}'.format(account.owner)
print('账户金额:{0}'.format(account.amount)
print('利于:{0}'.format(Account.interest_rate)
不能通过个体对象 来调用类变量
5. 类方法
类方法和类变量,属于类,不属于个体实例。
class Account:
interest_rate = 0.0568 #类变量 利率interest_rate
#构造方法
def _init_(self,owner,amuont):
self.owner = owner #创建并初始化实例变量owner
self.amount = amount
#类方法
@classmethod
def interest_by(cls, amt):
return cls.interest_rat * amt
#调用当前类变量*amt参数
interest = Account.interest_by(12000.0)
print ('计算利息:{0:.4f}'.format(interest))
类方法:第一个参数cls较为特殊
对比cls和self :cls 代表当前这一类;self 代表当前这一类的个体
封装性
封装隐藏了对象的内容细节,只保留有限的对外接口,外部调用者不用关心对象细节,使得操作对象简单。
1.私有变量
- 为防止外部调用者随意存取类的内部数据(成员变量),内部数据(成员变量)会被封装为“私有变量”。
- 私有变量,则在变量前加上双下划线(__).
class Account:
__interest_rate = 0.0568 #私有类变量 利率interest_rate
#构造方法
def _init_(self,owner,amuont):
self.owner = owner #创建并初始化实例变量owner
self.__amount = amount #创建并初始化私有变量__amount
def desc(self):
return "{0} 金额:{1} 利率:{2}.".format(self.owner, self.__amount, Account.__interest_rate)
私有变量:只能在类中访问 ;在类的外边无法访问私有变量
实例变量可私有,类变量也可私有
2.私有方法
私有方法与私有变量的封装是类似的,在方法前加上双下划线(__) 即是私有方法。
class Account:
__interest_rate = 0.0568 #私有类变量 利率interest_rate
#构造方法
def _init_(self,owner,amuont):
self.owner = owner #创建并初始化实例变量owner
self.__amount = amount #创建并初始化私有变量__amount
def __get_info(self):
return "{0} 金额:{1} 利率:{2}.".format(self.owner, self.__amount, Account.__interest_rate)
def desc(self):
print(self.__get_info()) #实际访问为__get_info(self)私有方法
同理,私有方法只能在类的内部访问
3.使用属性
为了实现对象的封装,在一个类中不应该有共有的成员变量,这些成员变量应该被设计成私有的,然后通过共有的set(赋值)和个体(取值)方法访问。
class Dog:
#构造方法
def _init_(self,name,age, sex = '雌性')
self.name = name # 创建和初始化实例变量name
self.__age = age # 创建和初始化实例变量age
#实例方法
def run(self):
print ("{}在跑...".format (self.name))
@property
def age(self): #代替get_age(self):
return self.__age
@age.setter
def age(self, age): #替代set_age(self, age)
self.__age = age
dog = Dog('老八',2)
print ('狗狗年龄:{}'.format(dag.age))
dog.age = 3 #dog._age(3)
print('修改后的狗狗年龄:{}'.format(dog.age))
属性对比
- 未使用属性
定义get()方法,放回私有实例变量__age
定义set()方法,通过age参数更新私有实例变量__age
- 使用属性
补充:
@property装饰器:说明这是取值的属性
若只定义 age(self)方法 则为只读方法 ,不可修改
补充:
@age.setter 装饰器
set方法通过传入形参给 age赋值 (方法命名和装饰器名字都要保持一致)
属性的命名 和 外部访问私有成员变量 一致 (age)
继承性
例如猫与动物之间的关系,猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”。猫是特殊类,猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称之为子类继承父类。
1.python中的继承
class Animal:
def __init__(self,name):
self.name = name #实例变量name
def show_info(self):
return "动物的名字:{0}“.format(self.name)
def move(self):
print ("{0}在动一动...").format(self.name)
class Cat(Animal):
def __init__(self, name, age):
super().__init__(name) #在构造子类前需要先构造父类
self.age = age #实例变量
cat = Cat('tom', 2)
cat.move()
print(cat.show_info())
super().init(name):构造子类前需要先构造父类,实际上为调用父类的构造方法
move():方法子类继承父类方法
2.多继承
例如:Java不支持多继承,但是python继承多继承。
class Horse:
def __init__(self, name):
self.name = name #实例变量name
def show_info(self):
return "马的名字:{0}".format(self.name)
def run(self):
print("马跑...")
class Donkey:
def __init__(self, name):
self.name = name #实例变量name
def show_info(self):
return "驴的名字:{0}".format(self.name)
def run(self):
print("驴跑了...")
def roll(self):
print("驴打滚...")
class Mule(Horse, Donkey):
def __init__(self, name, age):
super().__init__(name)
self.age = age #实例变量age
m = mule("骡马",1)
m.run() #继承父类 Horse方法
m.roll() #继承父类的Donkey方法
print(m.show_info()) #继承父类Horse的方法
多父类继承 顺序为从左到右
roll():马没有的方法 故而到驴子中继承
3.方法重写
方法重写:对父类已有的方法 进行改造
多态性
1.“多态”指对象可以表现出多种形态
2.例如,猫狗、鸭子都属于动物,它们都有“叫”和“动”等行为,但是“叫“的方式不同,”动”的方式也不同。
1.继承与多态
在每个子类继承父类,并重写父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。这些对象采用不同的方式实现父类方法。
class Animal:
def speak(self):
print('动物叫,但不知是哪个动物叫')
class Dog(Animal):
def speak(self):
print('小狗:汪汪叫')
class Cat(Animal):
def speak(self):
print('小猫:喵喵叫')
an1 = Dog
an2 = Cat
an1.speak()
an2.speak()
2.鸭子类型测试与多态
只有动态语言“python”中有鸭子类型测试;静态语言“java,c++”等,不出现鸭子类型测试。
1.鸭子类型测试指:
若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。
2.Python支持鸭子类型测试:
Python 解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。
def start(obj):#接收obj对象具有的speak()方法
obj.speak()
class Animal:
def speak(self):
print('动物叫,但不知是哪个动物叫')
class Dog(Animal):
def speak(self):
print('小狗:汪汪叫')
class Cat(Animal):
def speak(self):
print('小猫:喵喵叫')
class Car:
def speak():
print("小汽车,嘀嘀嘀")
start(Dog())
start(Cat())
start(Car())
1.设计一个函数start(),他接受具有“叫”speak()方法的对象
2.定义了几个类都有 speak()方法
3.start()可以接受所有speak方法对象