1、面向对象(OOP)概述
当解决一个问题的时候,面向对象会把事物抽象成对象的概念,就是说这个问题里面有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,问题得到解决。
例如:洗衣机里面放有脏衣服,怎么洗干净?
面向过程的解决方法:
1、执行加洗衣粉方法;
2、执行加水方法;
3、执行洗衣服方法;
4、执行清洗方法;
5、 执行烘干方法;
以上就是将解决这个问题的过程拆成一个个方法(是没有对象去调用的),通过一个个方法的执行来解决问题。
面向对象的解决方法:
1、我先弄出两个对象:“洗衣机”对象和“人”对象
2、针对对象“洗衣机”加入一些属性和方法:“洗衣服方法”“清洗方法”、“烘干方法”
3、针对对象“人”加入属性和方法:“加洗衣粉方法”、“加水方法”
4、然后执行
人.加洗衣粉
人.加水
洗衣机.洗衣服
洗衣机.清洗
洗衣机.烘干
解决同一个问题 ,面向对象编程就是先抽象出对象,然后用对象执行方法的方式解决问题。
面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。
面向对象是模型化的,你只需抽象出一个类,这是一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,管我们什么事?我们会用就可以了。
2、面向对象的三大特性
2.1、封装
- 类:用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。(语法格式如下,其中class是特有写法,用来声明类的,People为类名)
class People(object):
print("hhhh")
- 属性:属性分为私有属性和基本属性,基本属性在类的外部可以进行调用,而私有属性在类外部无法直接进行访问。
class People(object):
#定义基本属性
name="hh"
#定义私有属性
_Id="ghhhh"
- 方法:在类的内部,使用?def?关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
class People(object):
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def func(self):
print("hhjjj")
- 构造方法:构造方法__init__()?是类的特殊方法,可以携带参数,类的实例化操作会自动调用 __init__() 方法。
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
2.2、继承
继承某个类就可以调用这个类的方法和属性,语法如下:
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
s = student('ken',10,60,3)
s.speak()
继承分为单继承和多继承
class Person(object): # 定义一个父类
def talk(self): # 父类中的方法
print("person is talking....")
class Chinese(Person): # 定义一个子类, 继承Person类
def walk(self): # 在子类中定义其自身的方法
print('is walking...')
c = Chinese()
c.talk() # 调用继承的Person类的方法
c.walk() # 调用本身的方法
# 输出
person is talking....
is walking...
注意:创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__()需要父类施以援手。
class Rectangle(object):
def __init__(self, width, length): # 实例化传参时 将初始化参数
self.width = width
self.length = length
def get_area(self):
return self.width * self.length
class Square(Rectangle):
def __init__(self, width, length):
if width == length:
Rectangle.__init__(self, width, length) # 此处调用了父类方法,这里的self是正方形的实例,不是矩形的实例
else:
print('长度和宽度不相等,不能成为正方形')
square = Square(25, 25)
square.get_area()
square1 = Square(25, 22)
- 多继承:
-
一个子类可以继承多个父类是多继承 -
一层层继承下去是多重继承
class Base(object):
def play(self):
print('Base is playing!')
class A(Base): # 继承Base
name=""
def __init__(self,name):#带参数的构造函数
self.name=name
def play(self): # 自动覆盖父类的此方法
print('A is playing')
class B(Base): # 继承Base
money=""
def __init__(self,money):#带参数的构造函数
self.money=money
def play(self):
print('B is playing')
class C(A, B): # 继承A,B
#当带有参数时,写法如下:
def __init__(self,name,money):#带参数的构造函数
A.__init__(self,name)
B.__init__(self,money)
c = C()
c.play()
注意:父类中方法名相同,默认调用的是在括号中靠前面的父类的方法
- 方法重写:当子类继承父类之后,如果子类不想使用父类的方法,可以通过重写来覆盖父类的方法。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
class Parent: # 定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self): #重写父类方法
print('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
当子类重写父类方法之后,子类如果想再次调用父类的方法,可以使用这两种方法
#方法一
class C(A, B): # 继承A,B
def play(self): #覆盖父类
B.play(self) # 指定继承B类内的play方法
#方法二
class C(A, B):
def play(self):
super().play()
print('这是C')
- super()用法:super 函数可以调用父类的方法,在父类中也使用super函数之后,可以通过调用类的mro方法属性来查看继承关系
class Base(object):
def play(self):
print('Base is playing!')
class A(Base): # 继承Base
def play(self): # 自动覆盖父类的此方法
super().play() # 调用父类方法
print('A is playing!')
a = A()
a.play()
print(A.mro())#查看继承关系
#打印结果为:
Base is playing!
A is playing!
[<class '__main__.A'>, <class '__main__.Base'>, <class 'object'>]
2.3、多态
让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数,且不会影响到类的内部设计。例如:
#例1:
class Duck(object): # 鸭子类
def fly(self):
print("鸭子沿着地面飞起来了")
class Swan(object): # 天鹅类
def fly(self):
print("天鹅在空中翱翔")
class Plane(object): # 飞机类
def fly(self):
print("飞机隆隆地起飞了")
def fly(obj): # 实现飞的功能函数
obj.fly()
duck = Duck()
fly(duck)
swan = Swan()
fly(swan)
plane = Plane()
fly(plane)
===运行结果:===================================================================================
鸭子沿着地面飞起来了
天鹅在空中翱翔
飞机隆隆地起飞了
#例2:
class bus1(truck): #继承truck
name=""
def __init__(self,name):#带参数的构造函数
self.name=name
def func(self):
print(self.name + "是客车,汽车的重量是:" + self.heave + ",种类是:" + self.category)
class bus2(truck): #继承truck
name=""
def __init__(self,name):#带参数的构造函数
self.name=name
def func(self):
print(self.name + "是客车,汽车的重量是:" + self.heave + ",种类是:" + self.category)
class bus3(truck): #继承truck
name=""
def __init__(self,name):#带参数的构造函数
self.name=name
def func(self):
print(self.name + "是客车,汽车的重量是:" + self.heave + ",种类是:" + self.category)
def fp(obj): #定义打印方法
obj.func()
b=car.bus1("东风路28路公交车")#实例化对象1
b2=car.bus1("东风路906路公交车")#实例化对象2
b3=car.bus1("东风路B32路公交车")#实例化对象3
x=[b,b2,b3]#将对象存入列表中
#循环输出
for i in range(3):
fp(x[i])
print(x[i].truck_conduct())
print("________________")
|