侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 747 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

Python基础(28)之面向对象

zze
zze
2019-06-14 / 0 评论 / 0 点赞 / 734 阅读 / 5852 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

类的定义和使用

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def show(self):
        print(self.name)


# 实例化
person1 = Person('张三', 18, '男')
person2 = Person('李四', 20, '女')
person1.show()  # 张三
person2.show()  # 李四

类方法和静态方法

class A:
    @classmethod
    def print1(self):
        print('print in class method')

    @staticmethod
    def print2():
        print('print in static method')

A.print1()  # print in class method
A.print2()  # print in static method

接口和抽象类

由于 Python 没有抽象类、接口的概念,所以要实现这种功能得 abc.py 这个类库,具体使用如下:

接口

所有方法都必须在子类中实现。

import abc

class AInterface(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def func1(self): pass

class A(AInterface):
    def func1(self): pass

a = A()  
# 不实现则报错
# TypeError: Can't instantiate abstract class A with abstract methods func1

抽象类

部分方法在子类中实现。

import abc

class AInterface(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def func1(self): pass

    def func2(self): pass

class A(AInterface):
    def func1(self): pass

a = A()
a.func2()
# 不实现则报错
# TypeError: Can't instantiate abstract class A with abstract methods func1

三大特性

继承

单继承

class A:
    def print(self):
        print("print from A")

# B继承A
class B(A): pass

# C继承A
class C(A):
    def print(self):
        print('print from C')

b = B()
b.print()  # print from A
c = C()
c.print()  # print from C

当调用的方法在父类中已经存在同名方法,会默认调用子类的方法,如 C 类。如果子类中没有,则会调用父类的方法,如 B 类。

多继承

class A:
    def print(self):
        print('print from A')


class B:
    def print(self):
        print('print from B')


class C1(A, B): pass


class C2(B, A): pass


# C1类继承A类B类 C2类继承B类和A类
c1 = C1()
c1.print()  # print from A
c2 = C2()
c2.print()  # print from B

一个类继承多个类时,当调用的方法子类中没有时,会按继承顺序(从左到右)依次在父类中寻找并调用。

派生

子类拥有父类没有的方法或属性。

class A:
    def print(self):
        print('print from A')


class B(A):
    def myprint(self):
        print('print from B')


b = B()
b.print()  # print from A
b.myprint()  # print from B

钻石继承及 super() 的执行顺序

class A:
    def print(self):
        print("print from A")  # print from A  5

class B(A):
    def print(self):
        print('print from B')  # print from B  1
        print(super().print)  # <bound method C.print of <__main__.D object at 0x00000000021EC6D8>>  2
        super().print()

class C(A):
    def print(self):
        print('print from C')  # print from C  3
        print(super().print)  # <bound method A.print of <__main__.D object at 0x00000000021EC6D8>>  4
        super().print()

class D(B, C):
    pass

d = D()
d.print()

# result:
# print from B
# <bound method C.print of <__main__.D object at 0x00000000021EC6D8>>
# print from C
# <bound method A.print of <__main__.D object at 0x00000000021EC6D8>>
# print from A

image.png

多态

Python 原生支持多态。

Java 中的多态

public interface Animal {
    void talk();
}

public class Dog implements Animal{
    @Override
    public void talk() {
        System.out.println("wangwang");
    }
}

public class Pig implements Animal {
    @Override
    public void talk() {
        System.out.println("aoao");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.talk();
        Animal pig = new Pig();
        pig.talk();
    }
}

Python 中的多态

import abc

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def talk(self): pass

class Pig(Animal):
    def talk(self):
        print('aoao')

class Dog(Animal):
    def talk(self):
        print('wangwang')

dog = Dog()
dog.talk()
pig = Pig()
pig.talk()

封装

私有属性

属性或方法名前加双下划线声明私有属性或方法。对应 Java 中 private ,默认 public,无 protect(在类的外部仍然可以通过 实例._类名__属性名 调用)。

class Person:
    def __init__(self, name, age, gender, pwd):
        self.name = name
        self.__age = age
        self.gender = gender
        self.pwd = pwd

    def __getpwd(self):
        return self.pwd


person = Person('张三', 18, '男', '123')
print(person.name)
# print(person.__age)  # AttributeError: 'Person' object has no attribute '__age'
print(person._Person__age)  # 18
print(person.__getpwd())  # AttributeError: 'Person' object has no attribute '__getpwd'

封装属性

@property 可以将方法标识为一个属性。

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, new_name):
        self.__name = new_name

    @name.deleter
    def name(self):
        print('执行删除name操作')


p = Person('张三', 18)
print(p.name)  # 张三
p.name = '李四'
print(p.name)  # 李四
# 只是触发对应deleter装饰的函数,具体操作需在函数类完成
del p.name  # 执行删除name操作
print(p.name)  # 李四
0

评论区