zoukankan      html  css  js  c++  java
  • Python基础13 面向对象--类

    Python与C++、Java等众多语言一样,被视为一种面向对象的语言。

    如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。 

    一、类定义

    一个简单的类定义如下:

    class Person:
    
        def set_name(self, name):
            self.name = name
        
        def get_name(self):
            return self.name
    
        def greet(self):
            print("Hello, world! I'm {}".format(self.name))

    这里Person是类的名称。 Class语句创建独立的命名空间。

    >>> p = Person()
    >>> p.set_name('Mike')
    >>> p.greet()
    <__main__.Person object at 0x100614e10>
    <class '__main__.Person'>
    Hello, world! I'm Mike

    每个与类相关联的方法都会自动传递出参数self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。

    从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。

    实际上,可以随便给这个参数命名,但鉴于它总是指向对象本身,因此习惯上将其命名为self。

    self会自动传递,因此我们不需要传递它。

    二、构造函数

    类有一个名为 __init__() 的特殊方法称为构造函数,该方法在类实例化时会自动调用。

    __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。例如:

    class Person:
        def __init__(self, name):
            self.name = name
            print('__init__')
            print(self.name)

    实例化Person以及输出的结果示例为:

    >>> p = Person('John')
    __init__
    John

    以self为前缀的变量可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。

    self.name = name获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例。

    三、属性

    1、给属性指定默认值

    类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。

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

    2、修改属性的值

    可以通过实例或者类方法对属性进行修改。

    class Person:
        def __init__(self, name):
            self.name = name
            self.age = 8
            print('name:', self.name)
    
        def set_name(self, name):
            self.name = name
            print('name:', self.name)
    
    p = Person('Mike')
    p.name = 'Jack'
    print('name:', p.name)
    
    p.set_name('Rose')

    输出结果为:

    name: Mike
    name: Jack
    name: Rose

    四、继承

    一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。

    子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

    1、子类的构造函数__init__()

    在子类的构造函数里,必须调用父类的构造函数,这样才能正确的初始化对象。

    class Car:
        """汽车"""
    
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
    
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
    
    class ElectricCar(Car):
        """电动汽车的独特之处"""
    
        def __init__(self, make, model, year):
            """初始化父类的属性"""
            super().__init__(make, model, year)

    2、子类的属性和方法

    让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。

    class ElectricCar(Car):
        """电动汽车"""
    
        def __init__(self, make, model, year):
            """
            电动汽车的独特之处
            初始化父类的属性,再初始化电动汽车特有的属性
            """
            super().__init__(make, model, year)
            self.battery_size = 70
    
        def describe_battery(self):
            print("This car has a " + str(self.battery_size) + "-kWh battery")
    
    
    my_tesla = ElectricCar('tesla', 'model s', 2019)
    print(my_tesla.get_descriptive_name())
    my_tesla.describe_battery()

    输出结果为:

    2019 Tesla Model S
    This car has a 70-kWh battery

    3、重写(覆盖)父类的方法

    如果子类定义的方法与父类方法同名,则调用子类实例的时候Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。

    假设Car类有一个名叫fill_gas_tank()的方法,它对全电动汽车来说毫无意义,因此我们可以重写它。

    class ElectricCar(Car):
        --snip--
    
        def fill_gas_tank(self):
            """电动汽车没有油箱"""
            print("This car doesn't need a gas tank!")

    现在如果我们对电动汽车调用fill_gas_tank(),Python将忽略Car类中的方法fill_gas_tank()。

    五、静态方法和类方法

    1、静态方法

    静态方法的装饰器为staticmethod。

    静态方法的定义中没有参数self,可直接通过类来调用,表示该方法与具体实例无关。

    class MyClass:
    
        @staticmethod
        def smeth():
            print("This is a static method")

    可像下面这样直接使用:

    >>> MyClass.smeth()
    This is a static method

    2、类方法

    类方法的装饰器为classmethod。

    类方法的定义中包含类似于self的参数,通常被命名为cls。类方法也可以通过类直接调用,参数cls将自动关联到类。

    class MyClass:
    
        @classmethod
        def cmeth(cls):
            print("This is a class method of", cls)

    可像下面这样直接使用:

    >>> MyClass.cmeth()
    This is a class method of <class '__main__.MyClass'>

    六、抽象基类

    抽象基类是不能(至少是不应该)实例化的类,其职责是定义子类应实现的一组抽象方法。

    Python通过引入模块abc提供了官方解决方案,这个模块为抽象基类提供了支持。

    下面是一个简单的示例:

    from abc import ABC, abstractmethod
    
    
    class Talker(ABC):
        @abstractmethod
        def talk(self):
            pass

    抽象类不能实例化,并且没有实现抽象方法的子类也不能实例化:

    class Knigger(Talker):
        pass
    >>> Talker()
        Talker()
    TypeError: Can't instantiate abstract class Talker with abstract methods talk
    >>> Knigger()
        Knigger()
    TypeError: Can't instantiate abstract class Knigger with abstract methods talk

    我们可重新编写子类,实现要求的方法:

    class Knigger(Talker):
        def talk(self):
            print("Hi!")
    >>> k = Knigger()
    >>> k.talk()
    Hi!
  • 相关阅读:
    apache开源项目 -- Wicket
    读书笔记--《机器人时代》
    apache开源项目--dbutils
    apache开源项目--mina
    apache开源项目--OpenMeetings
    apache开源项目--lume
    apache开源项目--Sirona
    shared_ptr的简单实现
    高并发网络编程之epoll详解
    最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和
  • 原文地址:https://www.cnblogs.com/mazhiyong/p/12489264.html
Copyright © 2011-2022 走看看