Python学习三(面向对象)

1.面向对象和面向过程

        面向过程就是所有的事情已过程为主,关注的重点是过程,即第一步、第二步、第三步是什么。C语言就是典型的面向过程的语言。C语言需要只要先找到main函数,在main函数中一步一步的往下执行,比如如下代码:

Print('step1')
print('step2')
print('step3')

        面向对象关注点则是对象。比如一个人是一个对象,这个人身高、体重就是对象的属性,而跑、跳则是这个对象可以执行的相关操作。比如如下代码:

class 类名:
    def 方法1();
    
    def 方法2():

        简而言之,编写函数就是“面向过程”编写类就是“面向对象”

2.类和对象

        对象:具有行为属性。在进行描述的时候,属性多为名字。行为多为动词。

        :指一个类别。具有相同属性和行为的“对象”构成的一个整体。

        类和对象之间的关系:

        类是对象的抽象表现,对象是类的具体表现

        类是设计的蓝图,对象是根据蓝图设计出来的具体产物。

3.类的定义      

        在Python中,通过class关键字来定义一个类。这个类中可以包含零个多个属性和方法

class 类名:
    def 方法1();
    
    def 方法2():

 4.类的实例-对象

        当可以实现一个类之后,就可以通过这个类来实例化一个对象。这个对象包含了这个类的全部属性和方法

class person:   #类
    def a_name(self):   #方法
        print('xiaoming')

xiaoming = person() #根据person类实例一个对象
xiaohong = person() #根据person类实例一个对象
zhangsan = person() #根据person类实例一个对象

xiaoming.a_name()   #调用对象的方法
xiaohong.a_name()   #调用对象的方法
zhangsan.a_name()   #调用对象的方法

结果:
xiaoming
xiaoming
xiaoming

5.动态增加属性和方法

        很多时候我们需要根据需求给对象添加特殊的属性或方法,而这些属性和方法又不能跟其他对象共用,此时就需要动态来添加属性和方法了。

class person:   #类
    def a_name(self):   #方法
        print('xiaoming')

def age(self):  #动态增加的方法
    print("18")

xiaoming = person() #根据person类实例一个对象
xiaohong = person() #根据person类实例一个对象
zhangsan = person() #根据person类实例一个对象

xiaoming.gender = 'boy'    #动态增加属性gender
xiaoming.age = age    #动态增加方法age

xiaoming.a_name()   #调用对象的方法
xiaohong.a_name()   #调用对象的方法
zhangsan.a_name()   #调用对象的方法

print(xiaoming.gender)
xiaoming.age(xiaoming)

print(zhangsan.gender)
zhangsan.age(zhangsan)

结果:
xiaoming
xiaoming
xiaoming
boy
18
Traceback (most recent call last):
  File "d:/python/test_project/test.py", line 37, in <module>
    print(zhangsan.gender)
AttributeError: 'person' object has no attribute 'gender'

Traceback (most recent call last):
  File "d:/python/test_project/test.py", line 38, in <module>
    zhangsan.age()
AttributeError: 'person' object has no attribute 'age'

6.init(self)函数

        在python的init函数中,init前后各有2个下划线。而Init在每次被调用创建对象时,都会“自动调用”一次。参数self是必不可少的。类中定义的方法,第一个参数是固定的,命名为"self"。

class person:   #类
    def __init__(self):
        print("init")
    def a_name(self):   #方法
        print('xiaoming')

xiaoming = person() #根据person类实例一个对象
xiaohong = person() #根据person类实例一个对象
zhangsan = person() #根据person类实例一个对象

结果:
init
init
init

7.传入参数赋值属性

        很多时候,每个对象的属性值都是不相同的,就比如我们上边的代码,创建一个“名字”的方法,但是这个方法打印的内容都是相同的。这样就没有版本区分不同的对象了。所以,我们可以通过传入参数的方式赋值不同的属性值。

class person:   #类
    def __init__(self,name,age):
        self.name = name    #属性
        self.age = age        #属性
    def action(self):   #方法
        print('%s is running,age %d' %(self.name,self.age))

xiaoming = person('xiaoming',18) #根据person类实例一个对象
zhangsan = person('zhangsan',20) #根据person类实例一个对象

xiaoming.action()    #对象执行方法
zhangsan.action()    #对象执行方法

结果:
xiaoming is running,age 18
zhangsan is running,age 20

8.类属性

        类属性与当前类有绑定关系,与当前类创建的对象无关系

        对于类属性可以通过类名进行访问,也可以通过对象进行访问。但是,通过对象进行访问,是“只读”,不能进行修改

        对于实例属性,只能通过创建的对象进行访问不能通过类名进行访问

class person:   #类
    city = 'beijing'    #类属性
    def __init__(self,name,age):
        self.name = name    
        self.age = age
    def action(self):   #方法
        print('%s is running,age %d' %(self.name,self.age))

xiaoming = person('xiaoming',18) #根据person类实例一个对象
zhangsan = person('zhangsan',20) #根据person类实例一个对象

print(person.city)  #打印类属性
xiaoming.city = 'shanghai'  #通过对象修改类属性
print(xiaoming.city)    #打印对象类属性
print(person.city)  #打印类属性
print(zhangsan.city)    #打印对象类属性

print('>>>>>>>>>>>>>>')
person.city = 'nanjing'
print(xiaoming.city)    #打印对象类属性
print(person.city)  #打印类属性
print(zhangsan.city)    #打印对象类属性

结果:
beijing
shanghai
beijing
beijing
>>>>>>>>>>>>>>
shanghai
nanjing
nanjing

        从上述代码中,通过对象修改了类属性,看似修改成功了,其实并不是修改了类属性,只是动态地给对象创建了一个属性“city”,只不过这个属性名跟类属性的"city"属性名名字相同罢了。

9.类方法

        类方法需要使用@classmethod修饰

        类方法的第一个参数是固定的,命名为cls

        有两种方式来访问类方法,一种是通过类名来访问,另一种是通过对象名来访问不建议)。

        最好是通过类方法来访问类属性通过实例方法来访问实例属性

class person:   #类
    city = 'beijing'    #类属性
    def __init__(self,name,age):
        self.name = name    
        self.age = age
    def action(self):   #方法
        print('%s is running,age %d' %(self.name,self.age))

    @classmethod
    def move_city(cls,city): #类方法
        cls.city = city

xiaoming = person('xiaoming',18) #根据person类实例一个对象
zhangsan = person('zhangsan',20) #根据person类实例一个对象

print(person.city)
person.move_city('shenzhen')    #通过类名访问
print(person.city)
xiaoming.move_city("guangzhou") #通过对象名访问
print(person.city)

结果:
beijing
shenzhen
guangzhou

10.私有变量(private)

        如果希望类中的属性为私有属性,可以通过在属性名称前加两个下划线__来实现。此时只能通过内部进行访问外部不能访问

class person:   #类
    city = 'beijing'    #类属性
    def __init__(self,name,age):
        self.__name = name      #私有属性
        self.__age = age        #私有属性
    def action(self):   #方法
        print('%s is running,age %d' %(self.name,self.age))

    def get_name(self): #访问私有属性
        print(self.__name)

    def get_age(self):  #访问私有属性
        print(self.__age)

xiaoming = person('xiaoming',18) #根据person类实例一个对象
zhangsan = person('zhangsan',20) #根据person类实例一个对象

xiaoming.get_name()
xiaoming.get_age()

结果:
xiaoming
18

        如果直接调用实例进行访问的话,则会报错

print(xiaoming.__name)

结果:
Traceback (most recent call last):
  File "d:/python/test_project/test.py", line 38, in <module>
    print(xiaoming.__name)
AttributeError: 'person' object has no attribute '__name'

        那为什么要设置私有变量呢?因为这样可以在方法中对传入的参数进行判断,避免无效的参数输入

class person:   #类
    def __init__(self,name,age):
        self.__name = name      #私有属性
        self.__age = age        #私有属性

    def set_age(self,s_age):
        if not isinstance(s_age,(int)):
            raise TypeError('age false type')
        
        if(s_age > 0 and s_age < 100):
            self.__age = s_age
            print('age %d' %self.__age)
        else:
            print('age not correct:%d' %s_age)

xiaoming.set_age(18)
xiaoming.set_age(200)
xiaoming.set_age('18')

结果:
age 18
age not correct:200
Traceback (most recent call last):
  File "d:/python/test_project/test.py", line 52, in <module>
    xiaoming.set_age('18')
  File "d:/python/test_project/test.py", line 29, in set_age
    raise TypeError('age false type')
TypeError: age false type

11.继承

        当有两个属性高度类似的类时,就可以使用继承。如果类A继承了类B,那么A就是子类,B就是父类。子类一旦继承了父类,那么子类就会具备父类的一切特征。因此,父类能做的事情,子类也都可以做。

class fater:    #父类
    def __init__(self):
        self.name = 'fater'
        self.age = 58

class child(fater):    #子类
    def __init__(self):
        super().__init__()    #调用父类的init方法
        self.gender = 'boy'

laowang = fater();    #实例父类
print(laowang.name)    #打印父类属性
xiaowang = child();    #实例子类
print(xiaowang.name)    #打印子类继承父类的属性
print(xiaowang.gender)    #打印子类特有的属性
print(laowang.gender)    #打印父类中子类的属性(报错)

结果:
fater
fater
boy
Traceback (most recent call last):
  File "d:/python/test_project/test.py", line 64, in <module>
    print(laowang.gender)
AttributeError: 'fater' object has no attribute 'gender'

12.多重继承

        有时一个对象需要继承多个父类的属性,这就是多重继承。

class fater:    #父类
    def __init__(self,name,age):#属性
        self.name = name
        self.age = age
    
    def get_name(self):#方法
        print('fater name:%s' %self.name)

class mother:   #父类
    def __init__(self,name,age) -> None:    #属性
        self.name = name
        self.age = age      

    def get_name(self):#方法
        print('mother name:%s' %self.name)  

class child(fater,mother):#子类,按照先后顺序进行继承
    def __init__(self, name, age):#属性
        super().__init__(name, age) #调用父类的init方法
        self.gender = 'boy'

ft = fater('laowang',58);   #实例
mt = mother('laohong',55)   #实例
kid = child('xiaoming',10)  #实例
print(ft.name)  
print(mt.name)
print(kid.name) #父类属性
print(kid.age)  #父类属性
print(kid.gender)   #子类属性
kid.get_name()  #父类方法

结果:
laowang
laohong
xiaoming
10
boy
fater name:xiaoming

        可以看到,虽然同时继承了father和mother,但是调用父类的"name"方法时,调用的还是fater的方法。因为在继承时,father在前

        那把mother改到前面后试试。

class child(mother,fater):#子类,按照先后顺序进行继承

结果:
mother name:xiaoming

13.多态

class fater:    #父类
    def __init__(self,name,age):#属性
        self.name = name
        self.age = age
    
    def get_name(self):#方法
        print('fater name:%s' %self.name)


class child(fater):#子类
    def __init__(self, name, age):#属性
        super().__init__(name, age) #调用父类的init方法
        self.gender = 'boy'

    def get_name(self):
        print('child name:%s' %self.name)

ft = fater('laowang',58);   #实例
kid = child('xiaoming',10)  #实例
    
kid.get_name()

结果:
child name:xiaoming

        可以看到,child是从father处继承了属性和方法,child和father有同名的方法get_name,但是当调用child的get_name方法时,会自动调用自身的方法,而不会调用父类的方法。这就是多态。

        对于一个变量,只需要知道父类型,无需确切地知道它的子类型,就可以放心地调用方法,而具体调用的方法是作用在father还是child,由运行时该对象的确切类型决定,这就是多态的威力。调用方只管调用,不管细节,而当需要新增一种子类型是,只要确保方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值