python基础之面对对象基础(中)

接触python也有好几年了,一直处于学学忘忘的状态,没有形成具体框架,都是哪里不会问度娘,总这样学觉得不太踏实,还是打好基础心里稳一点。

但是也不是从最基本的安装环境,变量开始写,那种也没有什么技术含量,百度看看就好了。

所以本文合适学过python,但好久没用过的人看。

(1)单继承

继承的概念

在现实生活中,继承一般指的是子女继承父辈的财产。在面向对象中同样有继承,例如:

  • 猫的方法:喵喵叫、吃、喝

  • 狗的方法:汪汪叫、吃、喝

如果给猫和狗都创建一个类,那么猫和狗的所有方法都要写,如:

class:    
	def 喵喵叫(self):        
        print('喵喵叫')    
    def(self):        
        pass    
    def(self):        
        pass
class:    
    def 旺旺叫(self):        
        print('旺旺')    
    def(self):        
        pass    
    def(self):        
        pass

继承的写法

上面的代码中我们可以发现,吃,喝方法时一样的,但是写了两遍。
如果用继承的思想,我们可以这样:猫和狗都是动物(动物有吃,喝的方法)

class 动物(object):    
    def(self):        
        pass    
	def(self):        
        pass
class(动物):  # 继承动物类    
    def 喵喵叫(self):        
        print('喵喵叫')
class(动物):  # 继承动物类    
    def 旺旺叫(self):        
        print('旺旺')

所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法

示例

(1)

class Animal(object):    
    def eat(self):        
        print('正在吃饭')
class Cat(Animal):  # Cat类继承Animal类,Cat是子类,也称派生类,Animal类是父类,也称为基类    
    pass
class Dog(Animal):    
    pass
cat = Cat()
cat.eat()
dog = Dog()
dog.eat()

输出结果

正在吃饭
正在吃饭

示例中子类没有写任何方法,但是直接调用eat方法没有报错,这说明子类继承了父类的方法。
总结:在定义子类时要继承父类,只需要类名后面的小括号()中写上父类的名字,那么父类的属性、方法,会被继承给子类。

(2)

class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")


class Dog(Animal):
    def bark(self):
        print(f"{self.name} is barking.")


# 创建Animal对象并调用方法
animal = Animal("Generic Animal")
animal.eat()
animal.sleep()

# 输出:
# Generic Animal is eating.
# Generic Animal is sleeping.

# 创建Dog对象并调用方法
dog = Dog("Buddy")
dog.eat()
dog.sleep()
dog.bark()

# 输出:
# Buddy is eating.
# Buddy is sleeping.
# Buddy is barking.

在上面的示例中,定义了一个名为 Animal 的基类,具有 eatsleep 方法。然后,定义了一个名为 Dog 的子类,继承自 Animal 类,并添加了一个额外的 bark 方法。

通过使用单继承,Dog 类继承了 Animal 类的属性和方法。在 Dog 类中,可以直接调用 Animal 类的方法,如 eatsleep。此外,Dog 类还定义了自己的方法 bark

在示例中,首先创建了一个 Animal 对象,并调用了它的方法。然后,创建了一个 Dog 对象,并调用了它继承的 Animal 类的方法,以及它自己定义的 bark 方法。

(2)多继承

多继承概念

子类可以继承一个父类,那是否可以继承两个父类或多个呢?答案是肯定的,这就是python的多继承
在这里插入图片描述

C类可以继承A、B两个类, 可以将A,B中的方法继承过来,C拥有A,B的方法和属性

class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")


class Dog(Animal):
    def bark(self):
        print(f"{self.name} is barking.")


class Bird:
    def __init__(self, name):
        self.name = name

    def fly(self):
        print(f"{self.name} is flying.")


class Parrot(Bird, Animal):
    def speak(self):
        print(f"{self.name} is speaking.")


# 创建Dog对象并调用方法
dog = Dog("Buddy")
dog.eat()
dog.sleep()
dog.bark()

# 输出:
# Buddy is eating.
# Buddy is sleeping.
# Buddy is barking.

# 创建Parrot对象并调用方法
parrot = Parrot("Polly")
parrot.eat()
parrot.sleep()
parrot.fly()
parrot.speak()

# 输出:
# Polly is eating.
# Polly is sleeping.
# Polly is flying.
# Polly is speaking.

在上面的示例中,定义了三个类:AnimalDogBirdAnimal 类和 Bird 类分别具有自己的属性和方法。

然后,定义了一个名为 Parrot 的子类,继承自 Bird 类和 Animal 类。通过使用多继承,Parrot 类可以从两个父类中继承属性和方法。

在示例中,Dog 类只继承自 Animal 类,而 Parrot 类同时继承自 Bird 类和 Animal 类。因此,Dog 对象只能调用 Animal 类的方法,而 Parrot 对象可以调用 Bird 类和 Animal 类的方法。

(3)继承的传递

概念

在Python中,继承是可以传递的,这意味着子类不仅继承了直接父类的属性和方法,还继承了父类的父类(祖先类)的属性和方法。

当一个类继承自另一个类时,它将自动继承父类的所有属性和方法。如果父类本身也有父类,则子类也会继承父类的父类的属性和方法,以此类推,形成继承链。

示例

class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")


class Dog(Animal):
    def bark(self):
        print(f"{self.name} is barking.")


class Bulldog(Dog):
    def guard(self):
        print(f"{self.name} is guarding.")


# 创建Bulldog对象并调用方法
bulldog = Bulldog("Spike")
bulldog.eat()
bulldog.sleep()
bulldog.bark()
bulldog.guard()

# 输出:
# Spike is eating.
# Spike is sleeping.
# Spike is barking.
# Spike is guarding.

在上面的示例中,定义了三个类:AnimalDogBulldogDog 类继承自 Animal 类,Bulldog 类继承自 Dog 类。

因此,Bulldog 类不仅继承了 Animal 类的属性和方法,还继承了 Dog 类的属性和方法。这样就形成了继承链,使得 Bulldog 对象可以调用 Animal 类和 Dog 类的方法。

在示例中,创建了一个 Bulldog 对象,并调用了它继承的 Animal 类和 Dog 类的方法,以及它自己定义的 guard 方法。

(4)重写父类方法

概念

所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。

这意味着子类可以为继承的方法提供自己的实现,以满足特定需求或修改父类方法的行为。

示例

子类重写父类方法的过程很简单:在子类中定义一个与父类方法同名的方法即可。当子类对象调用该方法时,子类的方法将优先执行,而不会执行父类中的方法。

(1)伪代码

class 父类:  
    def 抽烟(self):      
        print('抽芙蓉王')  
	def 喝酒(self):        
        print('喝二锅头')
class 子类(父类):    # 与父类的(抽烟)同名方法,这就是重写父类方法    
    def 抽烟(self):        
        print('抽中华')    # 儿子比他爹有出息,抽好烟
        # 重写父类方法后,子类调用父类的方法时将调用的是子类的方法。
son = 子类()
son.抽烟()

输出结果:

抽中华

(2)

class Animal:
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("Animal makes a sound.")


class Dog(Animal):
    def make_sound(self):
        print("Dog barks.")


# 创建Animal对象并调用方法
animal = Animal("Generic Animal")
animal.make_sound()

# 输出:
# Animal makes a sound.

# 创建Dog对象并调用方法
dog = Dog("Buddy")
dog.make_sound()

# 输出:
# Dog barks.

在上面的示例中,定义了两个类:AnimalDogDog 类继承自 Animal 类,并重写了 make_sound 方法。

在父类 Animal 中,make_sound 方法打印出 “Animal makes a sound.”。然而,在子类 Dog 中,重写了该方法,并打印出 “Dog barks.”。

由于子类 Dog 重写了父类 Animalmake_sound 方法,因此调用 Dog 对象的 make_sound 方法时,执行的是子类的实现,而不是父类的实现。

(5)调用父类方法

概念

子类可以通过使用 super() 函数调用父类的方法。super() 函数提供了一种方便的方式,让子类能够访问并调用父类的方法。

通过 super() 函数,可以在子类中调用父类的方法,并传递必要的参数。这样可以在子类中扩展父类的方法,同时保留父类方法的行为。

示例

class Animal:
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("Animal makes a sound.")


class Dog(Animal):
    def make_sound(self):
        super().make_sound()
        print("Dog barks.")


# 创建Dog对象并调用方法
dog = Dog("Buddy")
dog.make_sound()

# 输出:
# Animal makes a sound.
# Dog barks.

在上面的示例中,定义了两个类:AnimalDogDog 类继承自 Animal 类,并在 make_sound 方法中调用了父类的方法。

在子类 Dogmake_sound 方法中,使用 super().make_sound() 调用了父类 Animalmake_sound 方法。然后,在子类中添加了额外的行为,即打印 “Dog barks.”。

在示例中,创建了一个 Dog 对象,并调用了它的 make_sound 方法。

通过使用 super().<method_name>,可以在子类中调用父类的方法,并在适当的位置扩展父类方法的行为。

(6)多态

概念

多态是面向对象编程的一个重要概念,它允许不同的对象对于相同的方法调用做出不同的响应。多态性使得我们可以通过统一的接口处理不同类型的对象,提高代码的灵活性和可扩展性。

在Python中,多态性是通过方法的动态绑定和运行时的类型判断实现的。当一个对象调用一个方法时,Python会在运行时根据对象的实际类型确定要执行的方法

示例

class Animal:
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        pass


class Dog(Animal):
    def make_sound(self):
        print("Dog barks.")


class Cat(Animal):
    def make_sound(self):
        print("Cat meows.")


# 创建Animal、Dog和Cat对象
animal = Animal("Generic Animal")
dog = Dog("Buddy")
cat = Cat("Kitty")

# 调用它们的make_sound方法
animal.make_sound()  # 未定义具体实现,什么也不输出
dog.make_sound()     # 输出:Dog barks.
cat.make_sound()     # 输出:Cat meows.

在上面的示例中,定义了一个基类 Animal 和两个子类 DogCat。这些类都有一个名为 make_sound 的方法,但是具体的实现在每个子类中是不同的。

创建了一个 Animal 对象和一个 Dog 对象,以及一个 Cat 对象。然后,分别调用它们的 make_sound 方法。

由于多态性的存在,虽然调用的是相同的方法 make_sound,但是实际执行的是根据对象的类型动态确定的方法。因此,Animal 对象的 make_sound 方法未定义具体实现,什么都不输出,而 Dog 对象的 make_sound 方法输出 “Dog barks.”,Cat 对象的 make_sound 方法输出 “Cat meows.”

(7)类属性和实例属性

概念

类属性

类属性是属于类本身的属性,它在类定义中声明,并且会被所有该类的实例共享。类属性可以通过类名或实例访问,也可以通过类的任意实例进行修改。它们在内存中只存在一份,对于所有该类的实例来说是相同的。

实例属性

实例属性是属于类的实例的属性,它在每个实例中单独存在,不会被其他实例共享。实例属性通常在类的构造方法中定义,每个实例可以具有不同的属性值。实例属性只能通过实例访问和修改,对于其他实例或类来说是不可见的

很明显实例属性范围小于类属性范围

示例

class Car:
    # 类属性
    wheels = 4

    def __init__(self, make, model):
        # 实例属性
        self.make = make
        self.model = model


# 访问类属性
print(Car.wheels)  # 输出:4

# 创建Car对象
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Civic")

# 访问实例属性
print(car1.make)  # 输出:"Toyota"
print(car2.make)  # 输出:"Honda"

# 修改实例属性
car1.make = "Ford"
print(car1.make)  # 输出:"Ford"
print(car2.make)  # 输出:"Honda"

# 修改类属性
Car.wheels = 3
print(car1.wheels)  # 输出:3
print(car2.wheels)  # 输出:3

类属性和实例属性的访问原理

类属性类对象可以访问,实例对象也可以访问,这与内存中保存的方式有关
在这里插入图片描述

上图中可以看出,所有实例对象的类对象指针指向同一类对象。实例属性在每个实例中独有一份,而类属性是所有实例对象共有一份。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值