(三)python基础之:面向对象基础

一、面向对象

面向对象是一种符合人类思维的编程方法,现实世界就是由对象和对象构成的,所以我们可以用代码将现实世界映射到开发中。 每一个对象都有他自己的状态和行为,以汽车为例:

状态:油耗,颜色,轴距,速度,材质......

行为:启动,行使,加减速,刹车......

二、类

类是构建对象的状态和行为的模板,以汽车为例,类就是汽车的设计图或者骨架图,而实例则是根据设计图制造出来的实物,被称作为对象。

例如:宝马88系中 红色,蓝色,黑色等。

定义一个类:

def car (object):
pass
#所有的类都会继承object类,不知道填什么就填这个类

三、类的属性和方法

类中定义的函数叫类的方法,类方法与普通函数的区别在于,其第一个参数固定为self,表示实际使用时对应的实例本身,可以使用init方法将一些强制的属性绑定进去。

1:定义一个Student类

class Car(object):
 #由于类是模板,当创建实例时,可以使用__init__构造方法将强制的属性绑定进去,self参数指向实例本身
       def __init__(self,speed):
        #给car定义speed属性
        self.speed = speed
    #定义一个打印汽车速度的方法(函数)
    def run(self):
        print('现在速度为:',self.speed)
        return  self.speed

2:传入参数

#创建student的实例,并传入数据
baoma = Car(100)

3:访问对象的属性

class Car(object):
    # speed = 0       #共用的类属性
    def __init__(self,speed,):
        self.speed = speed
    def run(self):
        print('现在速度为:',self.speed)
        return  self.speed

#创建Car的实例,并传入数据      
baoma = Car(100)

#调用baoma对象的speed属性。
print(baoma.speed)

#调用baoma的打印速度方法:
baoma.run()

运行结果:

L:/python项目库/面向对象编程/面向对象.py

100
现在速度为: 100

进程已结束,退出代码0

4:类的封装

因为在Student类中已经含有对象的属性,所以没必要在外部重新定义新的函数访问,我们可以在Student类中定义函数,这样的就叫封装。封装的好处是可以在类中新增方法。

新增打印汽车型号的方法。
class Car(object):
    def __init__(self,name,speed,):
        self.speed = speed
        self.name = name
    def run(self):
        print('现在速度为:',self.speed)
        return  self.speed
    #新增根据速度打印汽车型号的方法。
    def car_xh(self):
        if self.speed > 300:
            print(self.name,':','超级跑车')
        elif self.speed > 200:
            print(self.name,':','豪华型轿车')
        else:
            print(self.name,':','经济型轿车')

#创建Car的实例,并传入数据 
baoma = Car('baoma_X1',100)

#调用查询汽车型号的方法
baoma.car_xh()

5:访问限制

现在定义的类,外部可以访问到类的属性,这样很不安全,而且外部可以直接更改Car类的速度属性。

class Car(object):
    def __init__(self,name,speed,):
        self.speed = speed
        self.name = name
    def run(self):
        print('现在速度为:',self.speed)
        return  self.speed

#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)

#外部访问baoma的型号和速度
print(baoma.name,baoma.speed)

#外部更改宝马X1的参数
baoma.name = 'new_baoma_X1'
baoma.speed = 120

#更改后,再访问baoma的型号和速度
print(baoma.name,baoma.speed)

运行结果:

baoma_X1 100

new_baoma_X1 120

进程已结束,退出代码0

如果要让类的属性不被外部访问,直接在类属性的名称前加“__”两个下划线,这样就变成了一个私有变量(private)

更改为私有变量之后
Traceback (most recent call last):
  File "L:/python项目库/面向对象编程/面向对象.py", line 26, in 
    print(baoma.name,baoma.speed)
AttributeError: 'Car' object has no attribute '__name'

这样就不能直接访问了,但是又想让外部访问和更改怎么办?而且还要对更改的参数做检查。

6:改进版访问限制

外部访问方法:get_name,get_speed
class Car(object):
    def __init__(self,name,speed,):
        self.__speed = speed
        self.__name = name
    def get_name(self):
        return self.__name
    def get_speed(self):
        return  self.__speed
    def run(self):
        print('现在速度为:',self.__speed)
        return  self.__speed

#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)

#外部访问baoma的型号和速度
print(baoma.get_name(),baoma.get_speed())

运行结果:

baoma_X1 100

进程已结束,退出代码0

外部更改speed的方法:set_speed,并检查参数不能小于0
class Car(object):
    def __init__(self,name,speed):
        self.__speed = speed
        self.__name = name
    def get_name(self):
        return self.__name
    def get_speed(self):
        return  self.__speed
    def set_speed(self,speed):
        if speed > 0:
            self.__speed = speed
        else:
            raise ValueError('speed Erro')
    def run(self):
        print('现在速度为:',self.__speed)
        return  self.__speed

#创建Car的实例,并传入数据

baoma = Car('baoma_X1',100)
#调用set_speed方法,并传入错误参数
baoma.set_speed(0)

#外部访问baoma的型号和速度
print(baoma.get_name(),baoma.get_speed())

运行结果:

Traceback (most recent call last):
  File "L:/python项目库/面向对象编程/面向对象.py", line 34, in 
    baoma.set_speed(0)
  File "L:/python项目库/面向对象编程/面向对象.py", line 18, in set_speed
    raise ValueError('speed Erro')
ValueError: speed Erro

四、多态和继承

1:继承

##继承
class Animal(object):
    def speak(self):
        print('Animal is speaking:')

#定义Dog类,从父类继承
class  Dog(Animal):
    pass
class Cat(Animal):
    pass
#定义dog对象并调用继承来的Animal类的speak方法
dog = Dog()
dog.speak()

dog对象什么都没有做就能拿到Animal的方法,因为他即是Dog的子类也是Animal的子类。

2:多态

# -*- coding: utf-8 -*-

###多态
class Animal(object):
    def speak(self):
        print('Animal is speaking:')

#定义Dog类,从父类继承
class  Dog(Animal):
   def speak(self):
        print('汪汪')

class Cat(Animal):
    def speak(self):
        print('喵喵')

#定义一个外部函数speak_twice,传入的参数只要是带speak方法的对象就执行。
def speak_twice(animal):
    animal.speak()
    animal.speak()

speak_twice(Animal())
speak_twice(Dog()) 

1:在写一个函数speak_twice时,要调用Animal类,只需要保证函数中speak方法编写正确,不管你想调用子类Dog还是父类Animal还是新的子类,都可以拿到父类的speak方法。 2:在1中,如果子类的方法名和父类重复时,子类的优先执行,所以父类的方法即可继承有可以重写。

开闭原则:

对扩展开放:允许新增Animal子类;

对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

Python的鸭子理论

在Python中,只要你长得像鸭子那你就是鸭子 如: 在上面的多态例子中,函数speak_twice,只要你有speak方法那么就会执行,不管你的父类是谁

class yazi(object):
    def speak(self):
        print('嘎嘎')

speak_twice(yazi())

五、多重继承

继承和多态不仅可以继承父类的功能和行为,也可以继承多个父类,这样的叫多重继承。

# -*- coding: utf-8 -*-
"""
@author:leelian
@time:2018/9/2515:40
"""
class Bird(object):
    pass
class Mammal(object):
    pass
class Flyable(object):
    def say(self):
        print('我会飞!')
class Swimmable(object):
    def say(self):
        print('我会游泳')

#定义一种会飞的哺乳动物
class Bat(Flyable,Mammal):
    pass
#创建实例,并调用实例的方法
bat = Bat()
print(bat.say())

#如果多重继承中有多个父类,以第一个为主。
class Seagull(Mammal, Flyable, Swimmable):
    pass

#创建实例,并调用实例的方法)
seagull = Seagull()
seagull.say()

###类的定制__iter__
#构造一个迭代类
class FactorialIterator(object):
    def __init__(self):
        self.value = 1
        self.index = 1
    def __next__(self):
        self.value = self.value * self.index
        self.index = self.index + 1
        if self.index > 11:
                 raise  StopIteration()
        return self.value

class Factorial(object):
    def __init__(self):
        pass
    def __iter__(self):
        return FactorialIterator()

factorial = Factorial()
for n in factorial:
    print(n)

你可能感兴趣的:((三)python基础之:面向对象基础)