py第八章 面向对象 笔记

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

8.1类与对象的基础运用

类是抽象的对象是类的实例

8.1.1类的定义

class 类名:
    属性名=属性值
    def 方法名(self):
        方法体

类名:

大驼峰命名法首字母一般为大写

方法参数列表中的第一个参数是一个指代对象的默认参数self

class Car:
    wheels=4
    def drive(self):
        print('行驶')

8.1.2对象的创建与使用

对象名=类名()
car=Car()

访问属性或调用方法的语法格式

对象名.属性名
对象名.方法名()
print(car.wheels)
car.deive()

8.2类的成员

8.2.1 属性

属性根据声明方式有两类类属性和实例属性。

    • 类属性

类属性是声明在类內部、方法外部的属性。

例如上边的wheels。类属性可以通过类或对象进行访问但是只能通过类进行修改。

    • 实例属性

实例属性是在方法内部声明的属性py支持动态添加实例属性。

(1)访问实例属性

实例属性只能通过对象访问。

对象名.属性名

(2修改实例属性

对象名.属性名=修改后的值

(3)添加实例属性

对象名.属性名=添加的属性值

属性名好像可以重复

8.2.2方法

py中的方法有三种

实例对象、类方法、静态方法

    • 实例方法

实例方法定义在类內部以self为第一个形参。实例方法中的self代表对象本身他会在实例方法被调用的时候自动接收由系统传递的调用该方法的对象。

实例方法只能通过对象调用。

def drive(self):
    print('我是实例方法')

2.类方法

类方法定义在类内部

@classmethod 
def 类方法名(cls):
    方法体

类方法列表参数中的第一个参数是cls 代表类本身他会在类方法被调用的时候自动接收由系统传递的调用该方法得类。

类方法可以由类和对象调用。

类方法可以修改属性

class Car:
    whells=6
    @classmethod
    def stop(cls):
        print('我是类方法')
        cls.whells=7
car=Car()
print(car.whells)
print(Car.whells)
car.stop()   
print(car.whells)
print(Car.whells)

3.静态方法

静态方法定义在类內部

@staticmethod
def 静态方法名():
    方法体

静态方法可以通过类和对象调用。

静态方法内部不能直接访问属性或方法但可以通过类名访问属性或调用类方法。

class Car:
    whells=6
    @staticmethod
    def test():
        print('我是静态方法')
        print(f'类属性的值是{Car.whells}')
car=Car()
car.test() 

8.2.3私有成员

py默认成员是共有的。就是可以通过类或对象随意访问。

当属性名或方法名前边加“__”双下划线就代表当前的成员是私有的。

__属性名
__方法名

私有成员在类的外部不能直接访问但是可以调用类的公共方法访问。

class Car:
    __wheels=6
    def _drive(self):
        print('行驶')
    def test(self):
        print(f"轿车有{self.__wheels}轮胎")
        self._drive()
car=Car()
print(car.test())

8.3特殊方法

8.3.1构造方法

在创建的时候负责对象的初始化。每个类默认有一个__init__()方法如果显式的定义了__init__()方法那么创建对象的时候调用显式的构造方法否则调用默认的。

构造方法分两种

有参构造方法和无参构造方法。

当使用无参构造方法的时候所有对象的值都有相同的初始值。

当使用有参构造方法时所有对象的属性可以是不通的初值。

class Car:
    def __init__(self):
        self.color='红色'
    def drive(self):
        print(f"车的颜色是{self.color}")
car_one=Car()
car_one.drive()
car_tow=Car()
car_tow.drive()

class Car:
    def __init__(self,color):
        self.color=color
    def drive(self):
        print(f"车的颜色是{self.color}")
car_one=Car("红色")
car_one.drive()
car_tow=Car("蓝色")
car_tow.drive()

突然感觉这里的self和Java中的this差不多都表示本类。

构造方法每次创建对象都会被加载我是理解成构造对象时用的方法。

class Car:
    def __init__(self,color):
        self.color=color
        print('构造方法被加载')
    def drive(self):
        print(f"车的颜色是{self.color}")
car_one=Car("红色")
car_one.drive()
car_tow=Car("蓝色")
car_tow.drive()

8.3.2 析构方法

__del__()放法

是销毁对象时系统自动调用的特殊方法。每个类都有一个__del__()方法。如果一个类显式定义了析构方法销毁对象的时候会调用显式的如果没有显式定义就会调用默认的。

class Car:
    def __init__(self) -> None:
        self.color='蓝色'
        print('对象被创建')
    def __del__(self):
        print('对象被销毁')
car =Car()
print(car.color)
del car
print(car.color)

py会通过引用计数器销毁对象当引用计数器为0时系统会销毁对象。

8.4封装

封装是面向对象的重要特性之一它的基本思想是对外隐藏类的细节提供用于访问类成员的公开接口。

类的外部无须知道实现细节只需要使用公开接口便可以访问类的内容故在一定程度上保证了类内数据的安全。

为契合封装思想在定义类的时候需要满足2点要求

  1. 将属性声明为私有属性

  1. 添加两个供外界调用的公有方法分别用于设置或获取私有属性的值。

class Person:
    def __init__(self,name) -> None:
        self.name=name
        self._age=1
        #设置私有属性的方法
    def set_age(self,new_age):
        if 0<new_age<=120:
            self._age=new_age
        #获取私有属性的值
    def get_age(self):
        return self._age
    

person=Person('小明')
print(f'年龄为{person.get_age()}岁')
person.set_age(66)
print(f'年龄为{person.get_age()}岁')

8.5继承

8.5.1单继承

一个子类只能继承一个父类

class 子类名 (父类名)

和java一样子类继承会自动拥有父类的公有成员若在定义的时候不指明该类的父类那么就会默认继承基类object

#继承
# 单继承
class Cat(object):  #object写不写没啥意义
    def __init__(self,corlor) -> None:
        self.corlor=corlor
    def walk(self):
        print('走猫步~~~')
#定义继承Cat类的子类scottishFold
class ScottishFold(Cat):   #创建一个类
    pass
fold =ScottishFold("灰色")   #创建一个对象
print(f"{fold.corlor}的折耳猫")
fold.walk()

和java一样父类的私有属性和方法 子类是不能访问的。

class Cat(object):  #object写不写没啥意义
    def __init__(self,corlor) -> None:
        self._corlor=corlor
    def _walk(self):
        print('走猫步~~~')
#定义继承Cat类的子类scottishFold
class ScottishFold(Cat):   #创建一个类
    pass
fold =ScottishFold("灰色")   #创建一个对象
print(f"{fold.corlor}的折耳猫")
fold.walk()

8.5.2多继承

class 子类名(父类名1,父类名2···)

#多继承
#定义一个表示房子的类House
class House:
    def live(self):
        print('供人类居住')
#定义一个汽车类
class Car:
    def drive(self):
        print('方便人类出行')
#定义一个表示房车的类继承House和Car
class TouringCar(House,Car):
    pass
tour_car=TouringCar()
tour_car.live()
tour_car.drive()

如果两个父类都有相同的方法那么会调用先继承的类中的方法。

8.5.3重写

子类有时候感觉父类的方法不太合适就可以更改方法和java相似只需要写一个名字相同的就好了这样调用的时候就调用子类重写的方法了。如果重写后又想调用之前的方法了就可以用

super().方法名()

py中好像不能有方法的多态就是名字相同形参不同那种。py中这样写好像就是会只认识后边的方法。

?????????????????????????????????????????????

子类访问父类的方法就是可以用super().方法名。

然会就是

class Person():
    def say(self):
        print('666')
class Person2(Person):
     def say(self):
        print(999)
     def say(self):
        super().say()
     
p=Person2()
p.say()

如果我同时继承了多个父类父类中有同名方法我想调用某个父类的同名方法怎么办呢?

去博客了解了下发现有两种方法。

  1. 类名.方法名

  1. super(类前边的类,self).方法名

class   C1:
    def test(self):
        print('=========c1=======')
class C2:
    def test(self):
        print('=========c2=======')

class C3:
    def test(self):
        print('=========c3=======')
class C4(C1,C2,C3):
    def test(self):
        print('=========c4=======')
ctest=C4()
ctest.test()
class   C1:
    def test(self):
        print('=========c1=======')
class C2:
    def test(self):
        print('=========c2=======')

class C3:
    def test(self):
        print('=========c3=======')
class C4(C1,C2,C3):
    def test(self):
        C1.test(self)
        C2.test(self)
        C3.test(self)
        

        print('=========c4=======')
ctest=C4()
ctest.test()

class   C1:
    def test(self):
        print('=========c1=======')
class C2:
    def test(self):
        print('=========c2=======')

class C3:
    def test(self):
        print('=========c3=======')
class C4(C1,C2,C3):
    def test(self):
        super(C4,self).test()
        super(C1,self).test()
        super(C2,self).test()
        

        print('=========c4=======')
ctest=C4()
ctest.test()

8.6多态

#多态
class Cat:
    def shout(self):
        print('喵喵喵')
class Dog:
    def shout(self):
        print('汪汪汪')
def shout(obj):
    obj.shout()

cat=Cat()
dog=Dog()
shout(cat)
shout(dog)

重点是第八行其实是定义了一个方法书上说接口这个接口会接收一个对象然后调用对象的某个方法。

8.7运算符重载

py中赋予了运算符的特殊方法我们可以根据重写运算符的方法来达到便捷的目的。

举例

class Calculator:
    def __init__(self,number) -> None:
        self.number=number
    def __add__(self,other):
        self.number=self.number+other
        return self.number
    def __sub__(self,other):
        self.number=self.number-other
        return self.number
    def __mul__(self,other):
        self.number=self.number*other
        return self.number
    def __truediv__(self,other):
        self.number=self.number/other
        return self.number


claculator=Calculator(10)
print(claculator+5)
print(claculator-5)
print(claculator*5)
print(claculator/5)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6