“什么是快乐星球”
我们知道Python,Java等是面向对象的语言,本篇文章带你了解Python的面向对象的特征。
面向对象的三大特征
封装
作用:
提高程序的安全性。将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“_”。
实例:
我们先创建一个类:
class Car:
def __init__(self, brand):
self.brand = brand
def start(self):
print("发动汽车...")
在编译器里,在class的左边有一个减号‘-’,点一下就变成了这个样子,说明我们定义的属性都属于Car这个类。
class Car:...
那么我们到底怎么封装我们的实例属性呢。我们新建一个类属性price,在定义时在前面添加__,就对该属性实现了封装。在类的内部定义一个新的方法,并且在内部是可以使用被封装的对象。再强调一下在外部是无法使用的。
class Car:
def __init__(self, brand, price):
self.brand = brand
self.__price = price
def start(self):
print("发动汽车...")
def show_information(self):
print('品牌:', self.brand, '价格:', self.__price)
car = Car('奔驰', '1w')
car.show_information()
#print(car.__price)系统会直接报错
那我们想强行使用怎么办呢?可以,但违背了封装思想的初衷,因此封装操作是靠程序员的自觉来维护的,当看见两个下划线定义的属性就不要访问了。
print(car._Car__price)
继承
语法:
规则:
如果一个类没有继承任何一个类,则默认继承object,例如我们上面举的例子,我们在一个文件中只定义了一个类,它就是默认继承object;Python支持多继承;定义子类时,必须在其构造函数中调用父类的构造函数。
例子:
根据上面定义的类Car,我们定义一个他的子类Car_2,里面的特殊元素,也是他自己的元素定义一个speed。注意点是在新的类名后面要加上括号,把继承父类的名称写入,其次在要继承的方法前面加上关键字 super(). ,这样Car_2类也可以使用Car中的 show_infomation() 方法。这里调用里面的属性也是有讲究的,要和父类调用方法里面传入的参数相同。
class Car:# 继承object类
def __init__(self, brand, price):
self.brand = brand
self.price = price
def start(self):
print("发动汽车...")
def show_information(self):
print('品牌:', self.brand, '价格:', self.price)
class Car_2(Car):
def __init__(self, brand, price, speed):
super().__init__(brand, price)# 调用父类的方法
self.speed = speed
car = Car('周董的奔驰', '1w')
car_2 = Car_2('林总的劳斯莱斯', '999w', '300km/h')
car.show_information()
car_2.show_information()
print(car_2.speed)
*多继承:
定义两个类都是object类的,再定义一个C类,里面传入两个类名A,B,这就代表C继承了A类的同时继承了B类,他们的从属结构如下图:
class A(object):
pass
class B(object):
pass
class C(A, B):
pass
*方法重写
问题来源:
还是举出上面的例子,我们定义了一个子类Car_2,里面有新类属性speed,而我们调用用父类中的方法只能输出和他一样的brand和price这两个属性,访问speed还得另外输出有些麻烦。
作用:
如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写,子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法;子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法。
例子:
重写方法如下图,这时编译器的左边会有一个小圈,把鼠标放上去会显示他重写的类。这时他的好处就显示出来了,我们还是在外面调用它的方法 show_infomation() ,只不过这次可以输出子类中的属性speed了。
class Car_2(Car):
def __init__(self, brand, price, speed):
super().__init__(brand, price) # 调用父类的方法
self.speed = speed
def show_information(self):
super().show_information()
print('速度:', self.speed)
car = Car('周董的奔驰', '1w')
car_2 = Car_2('林总的劳斯莱斯', '999w', '300km/h')
car.show_information()
car_2.show_information()
*object类
说明:
是所有类的父类,因此所有类都有object类的属性和方法;内置函数dir()可以查看指定对象所有属性;object有一个__str__() 方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__() 重写。
多态
说明:
简单地说,多态就是"具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、走起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。