一、面向对象程序设计三大特性:
1.
封装
------
将属性和
⽅
法封装到
⼀
个抽象的类中 ;
2.
继承
------
实现代码的重
⽤
;
3.
多态
------
不同的对象调
⽤
相同的
⽅
法,产
⽣
不同的执
⾏
结果,增加代码的
灵活度 。
1.封装
类的私有属性和方法
私有属性/方法:对象不希望公开的属性/方法 ;
定义方式
在定义属性或
⽅
法时,在属性名或者
⽅
法名前 增加两个下划线,定义的就
是私有属性或方法。
对于私有属性和私有方法,只能在类的内部访问,类的外部无法访问
class Woman:
def __init__(self, weight=0, age=0, name=""):
# weight为私有属性
self.__weight = weight
# age为私有属性
self.__age = age
self.name = name
def __secret(self):
print("我的体重是%d千克,年龄是%d" % (self.__weight, self.__age))
def show_secret(self):
self.__secret()
if __name__ == '__main__':
w = Woman(45, 20, "小丽")
w.show_secret()
2.继承
一、继承的概念、语法和特点
继承的概念:
⼦
类拥有
⽗
类的所有
⽅
法和属性。
北京市昌平区建材城西路金燕龙办公楼一层
电话:400-618-9090
二、继承的语法
class
类名
(
⽗
类名
):
pass
⼦
类继承
⾃⽗
类,可以直接享受
⽗
类中已经封装好的
⽅
法,不需要再次开发
⼦
类中应该根据职责,封装
⼦
类特有的属性和
⽅
法
class Animal:
def __init__(self, name="小花"):
self.name = name
def sleep(self):
print('%d在睡觉' % self.name)
def eat(self):
print('%d在吃饭' % self.name)
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
def run(self):
print('%s的小猫%s在跑' % (self.color, self.name))
if __name__ == '__main__':
c = Cat("豆豆", "黄色")
c.run()
# 运行结果:黄色的小猫豆豆在跑
三、基类,派生类
dog
类是
animal
类的
⼦
类
,
animal
类是
dog
类的
⽗
类
,
dog
类从
animal
类
继承
dog
类是
animal
类的
派
⽣
类
,
animal
类是
dog
类的
基类
,
dog
类从
animal
类
派生
class Fish(Animal):
def __init__(self, name):
super().__init__(name)
def swimming(self):
print("%s游水" %self.name)
class Bird(Animal):
def __init__(self, name):
super().__init__(name)
def fly(self):
print("%s在飞" % self.name)
四、继承的传递性
C
类从
B
类继承,
B
类
⼜
从
A
类继承
;
那么
C
类就具有
B
类和
A
类的所有属性和
⽅
法
;
⼦
类拥有
⽗
类以及
⽗
类的
⽗
类 中封装的所有属性和
⽅
法 。
五、⽅法的重写
当
⽗
类的
⽅
法实现不能满
⾜⼦
类需求时,可以对
⽅
法进
⾏
重写
(override)
。
重写
⽗
类
⽅
法有两种情况:
1.
覆盖
⽗
类的
⽅
法
;
2.
对
⽗
类
⽅
法进
⾏
扩展 。
lass Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
def eat(self):
print('%s在吃猫粮' % self.name)
def run(self):
print('%s的小猫%s在跑' % (self.color, self.name))
class Fish(Animal):
def __init__(self, name):
super().__init__(name)
def swimming(self):
print("%s游水" % self.name)
class Bird(Animal):
def __init__(self, name):
super().__init__(name)
def fly(self):
print("%s在飞" % self.name)
def eat(self):
super().eat()
print('%s在吃虫子' % self.name)
if __name__ == '__main__':
c = Cat("豆豆", "黄色")
c.run()
c.eat()
b = Bird("小鸟")
b.eat()
# 黄色的小猫豆豆在跑
# 豆豆在吃猫粮
# 小鸟在吃饭
# 小鸟在吃虫子
六、⽗类的私有属性和私有⽅法
1.
⼦
类对象不能在
⾃⼰
的
⽅
法内部,直接访问
⽗
类的私有属性或私有
⽅
法;
2.
⼦
类对象 可以通过
⽗
类的公有
⽅
法间接访问到私有属性或私有
⽅
法;
私有属性、
⽅
法是对象的隐私,不对外公开,外界以及
⼦
类都不能直接访问
私有属性、
⽅
法通常
⽤
于做
⼀
些内部的事情 。
七、object 类
在
Python 3
中定义类时,如果没有指定
⽗
类,会默认使
⽤
object
作为该类
的基类
—— Python 3
中定义的类都是新式类 。
在
Python 2
中定义类时,如果没有指定
⽗
类,则不会以
object
作为基类 。
建议统一继承自
object
class
类名
(object):
pass
多态
不同的⼦类对象调⽤相同的⽗类⽅法,产⽣不同的执⾏结果
类属性和类⽅法
不需要创建类的对象,通过 类名
.
的
⽅式就可以访问类的属性或者调用类的方法 。
一、类属性
class A(object):
# name 为类属性,通过 A.name 访问
name = "tom"
def __init__(self):
# 属性 age 通过对象访问
self.age = 20
print(A.name)
a = A()
print(a.age)
二、类方法
- 用@classmethod 修饰的方法为类方法;
- 类方法的参数为 cls,在类方法内部通过 cls.类属性 或者 cls.类方法 来访问同一个类中的其他类属性和类方法;
- 类方法不需要实例化就可以调用,类方法只能访问同一个类中的类属性和类方法。
class A(object):
# name 为类属性
name = "tom"
def __init__(self):
# 属性 age 只能通过对象访问
self.age = 20
# show_name 为类方法
@classmethod
def show_name(cls):
print(cls.name)
A.show_name()
三、普通方法访问类属性或者类方法
在普通方法中通过
类名
.
类属性
或者
类名
.
类方法 来访问类属性和类方法
class A(object):
# name 为类属性
name = "tom"
# show_name 为类方法
@classmethod
def show_name(cls):
print(cls.name)
# set_name 为普通方法
def set_name(self, name):
A.name = name
A.show_name()
a = A()
a.set_name("mary")
A.show_name()
四、静态⽅法
如果需要在类中封装
⼀
个
⽅
法,这个
⽅
法既不需要访问实例属性 或者调
⽤
实例
⽅
法也不需要访问类属性或者调
⽤
类
⽅
法
,
这个时候,可以把这个
⽅
法封装
成
⼀
个静态
⽅
法。
- 用@staticmethod 修饰的方法为静态方法;
- 静态方法是独立存在的,不能访问类或者实例的任何属性和方法;
- 通过 类名.静态方法 调⽤静态⽅法 。
语法如下
@staticmethod
def
静态
⽅
法名
():
pass
class A(object):
# show_help 为类的静态方法
@staticmethod
def show_help():
print("静态方法")