文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python中的类class: 继承、覆盖、重写、重载、扩展、多态、封装

2023-09-14 13:09

关注

一、python中的类

使用 class 关键字创建类。类中有方法、属性。

1.1 __init__() 函数

类的内置 __init__() 函数。所有类都有一个名为 __init__() 的函数,它在启动类时执行。

使用 __init__() 函数将值赋给对象属性,或者在创建对象时需要执行的其他操作。

每次使用类创建新对象时,都会自动调用 __init__() 函数。

class Person:  nation = "China" #属性nation  def __init__(self, name, age):    self.name = name  #外部传入参数赋值给属性name    self.age = age     def get_nation(self):    print(self.nation) #对象中的方法是属于该对象的函数p1 = Person("Bill", 63) #创建名为 Person 的类,使用 __init__() 函数为 name 和 age 赋值:print(p1.name)print(p1.age)print(p1.nation)p1.get_nation()

1.2 self 参数

self 参数是对类的当前实例的引用,用于访问属于该类的变量。

它不必被命名为 self,您可以随意调用它,但它必须是类中任意函数的首个参数

实例

使用单词 mysillyobject 和 abc 代替 self:

class Person:  def __init__(mysillyobject, name, age):    mysillyobject.name = name    mysillyobject.age = age  def myfunc(abc):    print("Hello my name is " + abc.name)p1 = Person("Bill", 63)p1.myfunc()

1.3 修改对象属性

可以这样修改对象的属性:

p1.age = 40

1.4 删除对象属性

使用 del 关键字删除对象的属性:

del p1.age

1.5 删除对象

使用 del 关键字删除对象:

del p1

1.6 pass 语句

类定义不能为空,但若要写无内容的类 或类方法,使用 pass 语句来避免错误。

class Person:  passclss Person:  nation = "china"  def say_hi(self):    pass

二、继承: 子类继承父类

父类:

子类:在创建子类时将父类作为参数传入。

继承:  继承另一个类的所有方法和属性。

多继承:A类、B类是两个没有继承关系的类,C类即继承了A类又继承了B类。

print('---------------------多继承------------------------')class A:    pass class B:    pass class C(A, B):    pass

单继承:C类继承了B类,B类继承了A类,C、B、A是层次继承的关系。

 

print('---------------------单继承------------------------')class Animal:    pass class Animal1(Animal):    pass

2.0 代码例子:

#父类class Person:  def __init__(mysillyobject, firstname, lastname):    mysillyobject.name = firstname    mysillyobject.family = lastname  def myfunc(abc):    print("Hello my name is " + abc.name)#子类,继承class Student(Person):  def __init__(self, fname, year, lname):    super().__init__(fname, lname) # 调用父类的属性赋值方法    self.graduationyear = year  #子类自己的属性  def welcome(self):    #子类自己的方法    print("Welcome", self.name, self.family, "to the class of", self.graduationyear)x = Student("Elon", 2019, "Musk")x.welcome()

2.1 添加 __init__() 函数

要把 __init__() 函数添加到子类(而不是 pass 关键字)。

注释:每次使用类创建新对象时,都会自动调用 __init__() 函数。

为 Student 类添加 __init__() 函数:

class Student(Person):  def __init__(self, fname, lname):    # 添加属性等

当添加 __init__() 函数时,子类将不再继承父的 __init__() 函数。

注释:子的 __init__() 函数会覆盖对父的 __init__() 函数的继承。

如需保持父的 __init__() 函数的继承,请添加对父的 __init__() 函数的调用:

class Student(Person):  def __init__(self, fname, lname):    Person.__init__(self, fname, lname) #不建议如此使用

2.1.1 使用 super() 函数

Python 还有一个 super() 函数,它会使子类从其父继承所有方法和属性:

通过使用 super() 函数,您不必使用父元素的名称,它将自动从其父元素继承方法和属性。

class Student(Person):  def __init__(self, fname, lname):    super().__init__(fname, lname) #推荐方法

2.2 添加属性

把名为 graduationyear 的属性添加到 Student 类:

class Student(Person):  def __init__(self, fname, lname):    super().__init__(fname, lname)    self.graduationyear = 2019

例子中,2019 年应该是一个变量,并在创建 student 对象时传递到 Student 类。为此,请在 __init__() 函数中添加另一个参数:添加 year 参数,并在创建对象时传递正确的年份:

class Student(Person):  def __init__(self, fname, lname, year):    super().__init__(fname, lname)    self.graduationyear = yearx = Student("Elon", "Musk", 2019)

2.3 添加方法

把名为 welcome 的方法添加到 Student 类:

class Student(Person):  def __init__(self, fname, lname, year):    super().__init__(fname, lname)    self.graduationyear = year  def welcome(self):    print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)

提示:如果在子类中添加一个与父类中的函数同名的方法,则将覆盖父方法的继承。

三、扩展: 覆盖(or重写) /重载 (override/ reload)

3.1 扩展

如果在开发中,子类的方法中包含父类的方法,父类原本的方法是子类方法的一部分,就可以采用扩展的方式。

扩展的方式步骤:

  1.  在子类中重写父类的方法
  2.  在需要的位置使用 super().父类方法 来调用父类方法的执行
  3.  代码其他的位置针对子类的需求,编写子类特有的代码实现

第2点.关于super:

  1.  在python中super是一个特殊的类
  2. super()就是使用super类创建出来的对象
  3.  最常使用的场景就是,在重写父类方法时,让super().调用在父类中封装的方法
#单继承, 子类对父类扩展:新增方法、重写方法、子类中使用super().调用父类方法class Animal():    def eat(self):        print("吃")    def run(self):        print("跑")    def drink(self):        print("喝")    def sleep(self):        print("睡")class Dog(Animal):    def bark(self):        print("汪汪叫")class XiaoTianQuan(Dog):    def fly(self):        print("会飞")    def bark(self):        # 1. 针对子类特有的需求,编写代码        print("天籁之音")        # 2. 使用super(). 调用原本在父类中封装的方法        super().bark()        # 3. 增加其他子类的代码        print("OKOK")# 创建一个哮天犬对象xtq = XiaoTianQuan()xtq.bark()xtq.drink()xtq.sleep()

3.2 重载 overload

重载(Overload):指类中多个方法具有相同的名字,但参数类型不同(或返回类型?返回类型不一定严格相同,兼容即可?)的现象。重载的设定是为了方便用户操作,以相同的方法名实现特定的功能,同时匹配不同的参数类型以满足功能的扩展性和需求的多样性。重载并不局限于构造器方法,它可以适用于类中的任何方法。

重载可以解决用户输入多样性的问题。比如你在调用spark方法的时候,经常发现相同函数名后 跟着多种不同的输入参数类型。

注意:

//下面例子中,同一个类中 Rectangle()方法 定义了3个,但它们参数个数或类型均不同。//我们在实例中即可以输入double型、也可以输入string的参数到Rectangle()方法中,//解决了输入参数的兼容性问题。这就是reload。class Rectangle{            public double height;   public double width;       //定义无参方法0    public Rectangle() {    }        //定义方法1    public Rectangle(double height,double width) {         this.height=height;       //this指代当前对象,用于区分方法中的形参        this.weight=width;    }        //定义方法1    public Rectangle(String height,String width) {         this.height=Double.valueOf(height);        this.weight=Double.valueOf(width);    }        public void calcuArea() {                           System.out.println("面积为:"+height*width);    }}public class Test{    public static void main(String[] args) {        Rectangle rec=new Rectangle(1,2);       //创建实例1-调用方法1,输入参数是double型        rec.calcuArea();                        //                Rectangle rec1=new Rectangle("1","2");  //创建实例2-调用方法2,输入是string类型        rec1.calcuArea();                           }}

3.3 覆盖

覆盖(Override):指在继承中,父类的有些方法在子类中不适用,子类重新定义。

注意:

子类如何重写父类的方法?
前提:
规则一:重写方法不能比被重写方法限制有更严格的访问级别
(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限。)

规则二:参数列表必须与被重写方法的相同。
(需要注意的是如果子类方法的参数和父类对应的方法不一样,那就不是重写,而是重载)

规则三:返回类型必须与被重写方法的返回类型相同。

规则四:重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。

规则五:不能重写被标识为final的方法。

规则六:如果一个方法不能被继承,则不能重写它。比如父类的私有方法就不能被重写。

如果子类能够继承父类的某个方法, 那么子类就能够重写这个方法。

# 如果子类中重写了父类方法# 在使用子类对象调用方法时,会调用子类中重写的方法class XiaoTianQuan(Dog):    def fly(self):        print("会飞")    def bark(self):        print("OKOK")class TuDog(Dog):    def fly(self):        pass    def bark(self):        print("小土狗")# 创建对象1xtq = XiaoTianQuan()xtq.bark()xtq.drink()xtq.sleep()# 创建对象2tg = TuDog()tg.bark()tg.fly()

四、多态

4.1 多态

多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然以通过这个变量的调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。
当子类和父类存在相同的方法的时候,子类的方法会覆盖父类的方法,这样代码在运行时总会调用子类的方法,这就是多态。
判断一个实例是不是某个对象,可以使用isinstance()函数,是则输出True,反之输出False。

print('---------------------多态------------------------')class Animal:    def say(self):        print('Animal')class Dog(Animal):    def say(self):        print('Dog')class Cat(Animal):    def say(self):        print('Cat')animal = Animal()animal.say()dog = Dog()dog.say()cat = Cat()cat.say()print('-------------------------isinstance()----------------------')print(isinstance(dog, Dog))print(isinstance(dog, Cat))print(isinstance(dog, Animal))

五、封装

5.1封装

封装: 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。 这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。提高了程序的安全性。
在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“-”。

六、object类

6.1object类

object类是所有类的父类,因此所有类都有objec类的属性和方法。

内置函数dir()可以查看指定对象所有属性。 objec有一个_str_()方法,用于返回一个对于“对象的描述”,对于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对_str_()进行重写。

在这里插入图片描述

print('-----------------------------------------------------')class A:    passclass B:    passclass D(A):    passclass C(A, B):    def __init__(self, name, age):        self.name = name        self.age = ageprint('----------------------特殊属性-----------------------')x = C('ss', 10)print('----------------__dict__----------------')print(x.__dict__) # 实例对象的属性字典print(C.__dict__) # 类对象的属性字典print('----------------------------------------')print(x.__class__) # 输出了对象所属的类print(C.__bases__) # C类的父类类型的元组print(C.__base__) # C类的父类的第一个类print(C.__mro__) #查看类的层次结构print(A.__subclasses__()) # 子类的列表print('----------------------特殊方法-----------------------')print('--------------__add__整数相加操作----------------')a = 20b = 10c = a+bd = a.__add__(b)print(c)print(d)print('--------------__add__----------------')

在这里插入图片描述

 Python 继承

来源地址:https://blog.csdn.net/eylier/article/details/128961571

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯