iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python学习32(面向对象_3)
  • 864
分享到

python学习32(面向对象_3)

面向对象python 2023-01-31 07:01:03 864人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。即一个派生类(derived class)继承基类(bass class)字段和方法。继承也允许把一个派生

继承
面向对象编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。即一个派生类(derived class)继承基类(bass class)字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
例如,有这样一个设计,一个Cat类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例如,Cat是一个Animal)。

继承基本语法:
class 派生类名(基类名1 [, 基类名2....]):
'Optional class documentation string'
class_suite
基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。如果在继承元组中列了一个以上的基类,那么它就被称作”多重继承” 。

python支持多重继承

继承
  在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造方法中专门调用,即子类不会继承基类的__init__()方法。
在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数。
 Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找需要调用的方法,找不到才去基类中找)。
 子类只继承父类所有公有的属性和方法,并且也可以在子类中通过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,因此在子类中是无法通过父类名来访问的
继承的本质
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类 仅需继承父类而不必一一实现每个方法。

单继承
示例:
#encoding=utf-8
class Parent(object):#父类
    parentAttr = 100

    def __init__(self):
        print("调用父类构造方法")

    def parentMethod(self):
        print("调用父类方法")

    def setAttr(self,attr):
        Parent.parentAttr = attr

    def getAttr(self):
        print("Parent attribute:",Parent.parentAttr)

class Child1(Parent):#子类1
    def __init__(self):
        print('调用child1的构造方法')

    def childMethod(self):
        print("调用child1的方法")
        Parent.parentMethod(self)#子类里面,用父类调用父类方法,需要加self

class Child2(Parent):#子类2
    #没有实现__init__方法,则会调用基类的__init__方法

    def childMethod(self):
        print("调用child2的方法")
        self.parentMethod() #子类调用继承自父类的方法

if __name__ == "__main__":
    c1 = Child1()#实例化子类1
    c2 = Child2()#实例化子类2
    c1.childMethod()#调用子类自己的方法
    c2.childMethod()#调用子类自己的方法
    c1.parentMethod()#子类调用继承的父类的方法
    c1.setAttr(200)#子类调用父类的方法
    c1.getAttr()#子类调用父类的方法

在子类中调用基类方法 基类.method(self)
如果子类没有定义构造方法,实例化子类对象时候会调用基类的构造方法

子类调用基类方法
1、 Parent.parentMethod(self)
2、 self.parentMethod()
第一种是直接用父类的类名.方法名去调用父类的方法,但是需要注意的是,这种调用方法必须将self作为参数传进去并且作为第一个参数,表示指向这个类的实例本身。这种方法多用于方法重写时。

第二种是直接用self去调用父类的方法,为什么可以这样调用呢?因为一旦子类继承了父类,那么子类就拥有父类所有的公有方法和属性,所以此时父类的方法和属性就相当于子类自己了,所以可以直接用self去直接调用实例的方法,而不用再传入self参数了
子类调用基类构造方法
1、super(subclassName, self).__init__( [parameter1[,parameter2....]])
2、superclassName.__init__(self, [parameter1[,parameter2....]])

注意:
两次参数列表中的self参数都是必不可少的,如果基类的构造方法中有除了self参数外别的参数,调用时,也必须传入同等数量、同等类型的参数。当子类不定义自己的构造方法时,默认会自动调用父类的构造方法。Python中super函数只能在构造方法中使用。

#encoding=utf-8
class Animal(object):

    def __init__(self,type,color):
        self.type = type
        self.color = color

    def print_info(self):
        print(self.type,self.color)

class Cat(Animal):
    def __init__(self,type,color,age):
        #super(Cat,self).__init__(type,color)
        Animal.__init__(self,type,color)
        self.age = age

    def print_info(self):
        print(self.type,self.color,self.age)

cat = Cat("cat","black",5)

cat.print_info()

类间的关系判断
Issubclass(sub,parent)
判断子类

class Person(object):
    pass

class student(Person):
   pass

if issubclass(student,Person):
    print("student 是 Person的子类")

else:
    print("student 不是 Person的子类")

Isinstance(instance,class)
判断一个对象是否一个类的实例

class Person(object):
    pass

class Student(Person):
   pass

p = Person()
stu = Student()

if isinstance(p,Person):
    print("p 是Person的实例")

if isinstance(stu,Person):
    print("stu 是父类Person的实例")

if isinstance(stu,Student):
    print("stu 是子类Student的实例")

多重继承
Python支持多重继承,也就是一个子类可以有多个父类,定义子类时,括号中写多个父类,并且父类间用逗号隔开。
在多重继承中,子类有那么多的父类,那子类实例化时,构造方法是怎样调用的呢?
这里需要记住几点:
➢多重继承中,子类在没有定义自己的构造方法时,以第一个父类为中心。(默认调用第一个父类的构造方法)
➢如果子类重新定义了自己的构造方法,就不会调用父类的构造方法。但如果仍想调用父类的构造方法,这个时候调用哪个父类的构造方法,由你自己确定,并且多重继承时,调用具体哪个父类的构造方法时只能使用如下方法:
superclassName.__init__(self, [parameter1[,parameter2....]] )
➢如果父类中有同名的方法时,通过子类的实例对象去调用的该方法也是第一个父类中的方法。同样你可以用我们上边说的“子类调用基类方法”中的的方法去调用具体哪个父类中的方法。Parent.parentMethod(self)

默认调用第一父类的构造方法
class Person(object):
    def __init__(self,name):
        self.name = name
        print("Person 的构造方法")

class Animal(object):
    def __init__(self,name):
        self.name = name
        print("Animal的构造方法")

class Student(Person,Animal):#没有定义__init__默认调用第一父类的构造方法

    def get_name(self):
        return self.name

stu = Student("zhangsan")
print(stu.get_name())

子类指定调用父类的构造方法
class Person(object):
    def __init__(self,name):
        self.name = name
        print("Person 的构造方法")

class Animal(object):
    def __init__(self,name):
        self.name = name
        print("Animal的构造方法")

class Student(Person,Animal):#没有定义__init__默认调用第一父类的构造方法

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

    def get_name(self):
        return self.name

stu = Student("zhangsan",20)
print(stu.get_name())   

多个父类有同名方法,调用第一个父类的方法
class Person(object):
    def __init__(self,name):
        self.name = name
        print("Person 的构造方法")

    def print_info(self):

        print("Person的 print_info方法")
        return self.name

class Animal(object):
    def __init__(self,name):
        self.name = name
        print("Animal的构造方法")

    def print_info(self):

        print("Animal的 print_info方法")
        return self.name

class Student(Person,Animal):

    def get_name(self):
        return self.name

stu = Student("zhangsan")
#print(stu.get_name())
print(stu.print_info())#默认调用第一个父类的方法

指定之类方法调用父类中的同名方法
class Person(object):
    def __init__(self,name):
        self.name = name
        print("Person 的构造方法")

    def print_info(self):

        print("Person的 print_info方法")
        return self.name

class Animal(object):
    def __init__(self,name):
        self.name = name
        print("Animal的构造方法")

    def print_info(self):

        print("Animal的 print_info方法")
        return self.name

class Student(Person,Animal):

    def get_name(self):
        return self.name

    def print_info(self):
        Animal.print_info(self) #子类方法显式调用父类的同名方法

stu = Student("zhangsan")
#print(stu.get_name())
print(stu.print_info())#

多重继承 方法的调用顺序

如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

➢当类是经典类时,多继承情况下,会按照深度优先方式查找(py2才有)
➢当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者类继承了object类,那么该类便是新式类,否则便是经典类

class D:
    def bar(self):
        print("D.bar")

class C(D):
    def bar(self):
        print("C.bar")

class B(D):
    def bar(self):
        print("B.bar")

class A(B,C):
    def bar(self):
        print("A.bar")

a = A()
a.bar()

# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续
去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> C --> D# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了。
经典类(深度优先):首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错

新式类(广度优先):首先去A类中查找,如果A类中没   有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了

示例2:
class House(object):
    def __init__(self,name):
        print("Calling house constructor")

class Car(object):
    def __init__(self):
        print("Calling car constructor")

class CarHouse(House,Car):#没有构造方法
    pass

class BusHouse(House,Car):
    def __init__(self):
        #super(BusHouse,self).__init__("sr")
         Car.__init__(self)

c = CarHouse("ad")#CarHouse没有定义构造方法,默认调用第一类的构造方法
b = BusHouse()#BusHouse显式调用Car的构造方法

class House(object):
    def __init__(self,name):
        print("Calling house constructor")

class Car(object):
    def __init__(self):
        print("Calling car constructor")

class CarHouse(House,Car):
    pass

class BusHouse(House,Car):
    def __init__(self):
        super(BusHouse,self).__init__("sr")#此种方法还是会调用第一父类的构造方法
         #Car.__init__(self)

c = CarHouse("ad")
b = BusHouse()

class House(object):
    def getHeight(self):
        print("调用house类的方法")

class Car(object):
    def getHeight(self):
        print("调用Car类的方法")

class CarHouse(House,Car):
    def __init__(self):
        pass

    def carHeight(self):
        Car.getHeight(self)

c = CarHouse()
c.carHeight()

class House(object):
    def getHeight(self):
        print("调用house类的方法")

class Car(object):
    def getHeight(self):
        print("调用Car类的方法")

class CarHouse(House,Car):
    def __init__(self):
        pass

    def carHeight(self):
        #Car.getHeight(self)
        self.getHeight()  #默认调用第一父类的同名方法

c = CarHouse()
c.carHeight()

封装2
将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装。外界只能通过对象的方法访问对象,因此封装同时也实现了对象的数据隐藏。通过封装和数据隐藏机制,将一个对象相关的变量和方法封装为一个独立的软件体,单独进行实现和维护,并使对象能够在系统内方便地进行传递,另外也保证了对象数据的一致性并使程序易于维护,封装可以让调用者不用关心对象是如何构建的而直接进行使用。在Python中,所有的特性都是公开可用的,但是程序员应该在直接访问对象数据与操作数据时谨慎行事,因为他们可能无意中使得这些特性在某些方面不一致。

示例:
class Animal(object):

    def __init__(self,name):
        self.name = name
        print(self.name)

    def accessibleMethod(self):
        print("I have a self! current name is:")
        print(self.name)
        print("the secret message is:")
        self.__inaccessible()

    def __inaccessible(self):
        print("U cannot see me...")

    @staticmethod
    def staticmethod():
        print("this is a static method")

    def setName(self,name):
        print("setName:")
        self.name = name

    def getName(self):
        print("getName:")
        return self.name

a = Animal("learns")
print(a.getName)
a.setName("sr")
print("new name: ",a.getName())
a.staticmethod()
a.accessibleMethod()

property 方法
#encoding=utf-8
class Student(object):

    def __init__(self,name,age,score):
        self.name = name
        self.age = age
        self.__score = score

    def set_score(self,score):
        if not isinstance(score,int):
            raise ValueError("score must be an interger!")

        if score < 0 or score > 100:
            raise ValueError("score must be between 0 - 100!")
        self.__score = score

    def get_score(self):
        return self.__score

s = Student("tom",19,90)
print("score is: ",s.get_score())

try:
    s.set_score(999)
except Exception as e:
print("score error")

这样就不能对score进行随便设置了。但是上面的调用方法略显复杂,没有直接使用属性简单。

#encoding=utf-8
from datetime import datetime
class Student(object):
    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self,value):
        self._birth = datetime.strptime(value,"%Y-%m-%d")
        print(self._birth)

    @property
    def age(self):
        currentTime = datetime.now()
        currentDate = currentTime.strftime("%Y-%m-%d")
        timedelta = datetime.strptime(currentDate,"%Y-%m-%d") - self._birth

        return timedelta.days // 365

if __name__ == "__main__":
    s = Student()
    s.birth = "1992-08-18"#调用 def birth(self,value):函数,并把置赋值给 self._birth
    print("现在年龄: ",s.age)#打印age()函数的返回值

上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。

多态
方法多态1

#encoding=utf-8
class F1(object):
    pass

class S1(F1):

    def show(self):
        print("S1.show")

class S2(F1):

    def show(self):
        print("S2.show")

def func(obj):
    obj.show()

s1_obj = S1()
func(s1_obj)

s2_obj = S2()
func(s2_obj)

多态方法2
#encoding=utf-8
class Calculator:

    def count(self,args):
        return 1

calc = Calculator()

from random import choice

obj = choice(["hello,world",[1,2,3],calc])

print(obj)

print(type(obj))

print(obj.count("a"))#当obj为calc实例对象时候,会调用count()方法

多态-”鸭子类型“
#encoding=utf-8
class Duck(object):
    def quack(self):
        print("Quaaaaaack!")

    def feathers(self):
        print("The duck has white and gray feathers.")

class Person(object):
    def quack(self):
        print("The person imitates a duck.")

    def feathers(self):
        print("The person takes a feather from the ground and shows it.")

def in_the_forest(duck):
    duck.quack()
    duck.feathers()

def game():
    donald = Duck()
    john = Person()
    in_the_forest(donald)
    in_the_forest(john)

game()

多态—运算符多态
#encoding=utf-8
def add(x,y):
    return x + y

print(add(1,2))

print(add("hello","world"))

print(add(1,"abc"))

方法重写
在类层次结构中,当子类的成员变量与父类的成员变量同名时,子类的成员变量会隐藏父类的成员变量;当子类的方法与父类具有相同的名字、参数列表、返回值类型时,子类的方法重写(overriding)了父类的方法,在父类定义的方法就被隐藏。“隐藏”的含义是,通过子类对象调用子类中与父类同名的变量和方法时,操作的是这些变量和方法是在子类中的定义。子类通过成员变量的隐藏和方法的重写可以把父类的状态和行为改成为自身的状态和行为。重写是指子类重写父类的成员方法。子类可以改变父类方法所实现的功能,但子类中重写的方法必须与父类中对应的方法具有相同的方法名。也就是说要实现重写,就必须存在继承。简单来讲,就是如果父类的方法不能满足子类的需求,子类就可以重写从父类那继承过来的方法。

重写父类的方法
#encoding=utf-8

class Person(object):
    def getInfo(self):
        print("Person info")

    def parent_m(self):
        print("父类未被重写的方法")

class Student(Person):
    def getInfo(self):
        print("Stuent info")

stu = Student()
stu.getInfo()#调用子类自己的重写的父类方法
stu.parent_m()#调用从父类继承的未重写的方法

--结束END--

本文标题: python学习32(面向对象_3)

本文链接: https://www.lsjlt.com/news/191197.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python学习32(面向对象_3)
    继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。即一个派生类(derived class)继承基类(bass class)字段和方法。继承也允许把一个派生...
    99+
    2023-01-31
    面向对象 python
  • Python - 面向对象学习
    本节内容: 面向对象编程介绍为什么要用面向对象进行开发?面向对象的特性:封装、继承、多态类、方法、  引子你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是...
    99+
    2023-01-31
    面向对象 Python
  • Python学习 :面向对象 -- 三大
    面向对象的三大特性 一、封装 把数据、值、变量放入到对象中 构造方法 _init_方法 特殊作用: 在 obj = 类名() 执行时: 内部自动执行两个步骤: 1、创建对象 2、通过对象执行类中的一个特殊方法(_init_方法) ...
    99+
    2023-01-30
    三大 面向对象 Python
  • Python学习之面向函数转面向对象详解
    还记得前文函数章节的‘函数的定义与使用’章节么?今天我们就来针对 类 进行一个综合练习,利用所学的面向对象编程、类 的知识将我们之前做的面向函数编写的学生信息...
    99+
    2024-04-02
  • Python学习教程:面向对象学习实力讲解
    类的实现class Cat:"""猫科动物类"""tag='我是家猫 'def __init__ (self,name,age=0): #没有默认值必须要传,且写在...
    99+
    2023-06-02
  • js 面向对象学习笔记
    目录数据赋值拷贝值类型赋值--函数形参&实参引用类型赋值对象的动态性delete删除属性数据赋值拷贝 1、值得赋值是独立的 num1=12; num1=num2 将存储值赋值...
    99+
    2023-05-18
    js 面向对象
  • Python 3 学习笔记:面向对象编程
    概述 面向对象编程(Object Oriented Programming,即 OOP),是一种程序设计思想,比面向过程编程更加灵活,更易扩展。 Python 在设计的时候就是按照面向对象编程的思想设计的,像我们前面学过的各种数据类型,如字...
    99+
    2023-01-31
    面向对象 学习笔记 Python
  • python学习笔记:第16天 面向对象
    目录 ⼀、类的成员介绍: 二、类的成员-变量 三、类的成员-方法 四、类的成员-属性 五、私有属性 ...
    99+
    2023-01-30
    面向对象 学习笔记 python
  • python学习笔记:第17天 面向对象
    一、类与类之间的依赖关系 ⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进⾏归类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类 中存在以下关系: 依赖关系 关联关系...
    99+
    2023-01-30
    面向对象 学习笔记 python
  • Java面向对象:抽象类的学习
    本文介绍了抽象类的基本语法概念,什么是抽象类. Java中抽象类的语法,抽象类的特性 抽象类的作用(抽象类和普通类的区别) 用抽象类实现多态… 抽象类的学习 一.什么是抽象类二.抽象类语...
    99+
    2023-09-11
    java 学习 jvm
  • Scala 学习之面向对象(3)
    ==> 类        ---> 类的定义class Student{     // 定义属性     private var stuName:String = "Tom"     private vat stuAge:Int...
    99+
    2023-01-31
    面向对象 Scala
  • Python学习之面向对象编程详解
    目录什么是面向对象编程(类)类的关键字 - class类的定义与使用类的参数 - selfself 的解析与总结类的构造函数构造函数的创建方法关于对象的生命周期什么是面向对象编程(类...
    99+
    2024-04-02
  • Java面向对象:接口的学习
    本文介绍了Java中接口的基本语法, 什么是接口, java中的接口 语法规则, 接口的使用,接口的特性,如何实现多个接口,接口间的继承,以及抽象类和接口的区别 Java接口的学习 一.接口的概念二.Java中的接口1.接口语...
    99+
    2023-08-17
    java 学习 android
  • 从0开始的Python学习014面向对象
     简介 到目前为止,我们的编程都是根据数据的函数和语句块来设计的,面向过程的编程。还有一种我们将数据和功能结合起来使用对象的形式,使用它里面的数据和方法这种方法叫做面向对象的编程。 类和对象是面向对象编程的两个重要方面。对于类和对象的关...
    99+
    2023-01-31
    面向对象 Python
  • 学习python的第十八天(面向对象编程
    一.面向对象编程 ​ 面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、然后干什么…… 与工厂的工艺流程差不多,前后都有影响 优点:复杂的问题流程化,进而简单化,调理清晰. 缺点:拓展性不行 二.对...
    99+
    2023-01-31
    面向对象 python
  • python学习之面向对象程序设计的一些
    将属于一类的对象放在一起:     如果一个函数操纵一个全局变量,那么两者最好都在类内作为特性和方法实现。    不要让对象过于亲密:     方法应该只关心自己实例的特性,让其他实例管理自己的状态。 简单就好:     让方法小巧起来,...
    99+
    2023-01-30
    程序设计 面向对象 python
  • python面向对象
    python面向对象 目录: 1.类的定义和使用 2.类的封装 3.类的继承 4.多态   1.类的定义和使用 查、增加、修改、删除、初始化方法、实例化 __init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这...
    99+
    2023-01-30
    面向对象 python
  • python 面向对象、类、对象
    class 类 object 对象 object-oriented programming 面向对象,简称OOP attribute 属性 method 方法 inheritance 继承 python中通过类和对象来实现 ...
    99+
    2023-01-31
    面向对象 对象 python
  • python 面向对象
    面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序...
    99+
    2023-01-30
    面向对象 python
  • Python|面向对象
    #一、类、对象定义及使用 #定义类语法:class 类名(父类):代码块注意:()可有可无 #class Student: #class Student(): #创建对象(实例)语法:对象名=类名() 注意:Java语言在实例化对...
    99+
    2023-01-30
    面向对象 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作