面向对象的三大属性

一:继承

1,面向对象中的继承表示的是类与类之间的关系(什么是什么的关系),在python3中,所有的类都会默认继承object类,继承了object类的所有类都是新式类,如果一个类没有继承任何父类,那么__bases__属性就会显示<class ‘object‘>。

2,继承可以分为单继承和多继承。

# 单继承
class Parent:pass
class Son(Parent):pass   # 继承关系
# Son继承了Parent
print(Son.__bases__)  # 内置的属性
print(Parent.__bases__)  # 内置的属性

# 多继承
class Parent1:pass
class Parent2(Parent1):pass
class Parent3:pass
class Son(Parent2,Parent3):pass   # 继承关系
print(Parent2.__bases__)
print(Son.__bases__)

3,对象使用名字的顺序: 先找对象自己内存空间中的,再找对象自己类中的,再找父类中的。

class Animal:
    role = ‘Animal‘
    def __init__(self,name,hp,ad):
        self.name = name     # 对象属性 属性
        self.hp = hp         #血量
        self.ad = ad         #攻击力
    def eat(self):
        print(‘%s吃药回血了‘%self.name)

class Person(Animal):
    r = ‘Person‘
    def attack(self,dog):   # 派生方法
        print("%s攻击了%s"%(self.name,dog.name))

    def eat2(self):
        print(‘执行了Person类的eat方法‘)
        self.money = 100
        self.money -= 10
        self.hp += 10

class Dog(Animal):
    def bite(self,person):  # 派生方法
        print("%s咬了%s" % (self.name, person.name))

# 继承中的init
alex = Person(‘alex‘,10,5)
print(Person.role)
print(alex.__dict__)
dog = Dog(‘teddy‘,100,20)
print(dog.__dict__)

# 继承中的派生方法
alex = Person(‘alex‘,10,5)
dog = Dog(‘teddy‘,100,20)
alex.attack(dog)
dog.bite(alex)

# 继承父类的方法:自己没有同名方法
alex = Person(‘alex‘,10,5)
dog = Dog(‘teddy‘,100,20)
alex.eat2()
alex.eat()
dog.eat()

# class Animal:
#     def __init__(self,name,sex,kind):
#         self.name = name
#         self.sex = sex
#         self.kind = kind
#     def eat(self):
#         print(‘%s is eating‘%self.name)
#
#     def drink(self):
#         print(‘%s is drinking‘%self.name)
#
# class Cat(Animal):
#     def climb(self):
#         print(‘%s is climbing‘%self.name)
#
# class Dog(Animal):
#     def watch_door(self):
#         print(‘%s is watching door‘%self.name)

# 1.确认自己没有init方法
# 2.看看有没有父类
# 3.发现父类Animal有init
# 4.看着父类的init方法来传参数
#tom = Cat(‘tom‘,‘公‘,‘招财猫‘)   # 实例化对象
# tom.eat = ‘猫粮‘
# print(Cat.__dict__)   # Cat.__dict__ Cat类的命名空间中的所有名字
# print(tom.__dict__)   # tom.__dict__ 对象的命名空间中的所有名字
# tom.eat()   # 先找自己对象的内存空间 再找类的空间 再找父类的空间
# tom.climb()   # 先找自己的内存空间 再找类的空间

4,self.名字的时候,不要看self当前在哪个类里,要看这个self到底是谁的对象

class Parent:
    def func(self):
        print(‘in parent func‘)
    def __init__(self):
        self.func()

class Son(Parent):
    def func(self):
        print(‘in son func‘)

s = Son()

5,object 类

class A:
#     ‘‘‘
#     这是一个类
#     ‘‘‘
    pass

a = A()
print(A.__dict__)  # 双下方法 魔术方法
# 创建一个空对象
# 调用init方法    —— 调用了么? 调用了
# 将初始化之后的对象返回调用处

6,在单继承中,如何给一个类的对象增加派生属性呢?

详见如下代码:

class Animal:
    def __init__(self,name,hp,ad):
        self.name = name     # 对象属性 属性
        self.hp = hp         #血量
        self.ad = ad         #攻击力
    def eat(self):
        print(‘eating in Animal‘)
        self.hp += 20

class Person(Animal):
    def __init__(self,name,hp,ad,sex):
        # Animal.__init__(self,name,hp,ad)
        #次为方法一
        # super(Person,self).__init__(name,hp,ad)
        #此为方法二
        super().__init__(name, hp, ad)
        #此为方法二简写(常用)
        # 在单继承中,super负责找到当前类所在的父类,在这个时候不需要再手动传self
        self.sex = sex      # 这个就是增加的派生属性
        self.money = 100
    def attack(self,dog):   # 派生方法
        print("%s攻击了%s"%(self.name,dog.name))
    def eat(self):                         # 重写
        super().eat()  # 在类内 使用 super()方法找父类的方法
        print(‘eating in Person‘)
        self.money -= 50

class Dog(Animal):
    def __init__(self,name,hp,ad,kind):
        Animal.__init__(self,name,hp,ad)
        self.kind = kind    # 派生属性
    def bite(self,person):  # 派生方法
        print("%s咬了%s" % (self.name, person.name))

alex = Person("zhangsan",100,10,"male")   # 实例化
#print(alex.__dict__)
# tg = Dog(‘到哥‘,100,50,‘藏獒‘)
# print(tg.__dict__)
# 父类有eat 子类没有
# alex.eat() # 找父类的
# 子类有eat 不管父类中有没有
# alex.eat() # 找子类的
# 当子类中有,但是我想要调父类的
# Animal.eat(alex)          #指名道姓
# super(Person,alex).eat()  # super(子类名,子类对象)方法   —— 一般不用
# 子类父类都有eat方法,我想执行父类的eat和子类的eat
#alex.eat()  # 执行子类的eat

7,多继承之钻石继承

对于多继承中的新式类,寻找名字的顺应该遵循广度优先。类名.mro() 可以查询广度优先的遍历顺序。

例如下面的程序:

class A:
    def func(self):
        print(‘A‘)
class B(A):
    pass
    # def func(self):
    #     print(‘B‘)
class C(A):
    pass
    # def func(self):
    #     print(‘C‘)
class D(B):
    pass
    # def func(self):
    #     print(‘D‘)
class E(B,C):
    pass
    # def func(self):
    #     print(‘E‘)
class F(D,E):
    pass
    # def func(self):
    #     print(‘F‘)
f = F()
f.func()
print(F.mro())  # 查看广度优先的遍历顺序,其遍历顺序为 F-D-E-B-C-A

【附】:pyrhon3 中的新式类遵循的广度优先算法图示

8,当遇到多继承和super时,应遵循以下的情况:

(1)找到这个对象对应的类。

(2)将这个类的所有父类都找到画成一个图

(3)根据图写出广度优先的顺序

(4)再看代码,看代码的时候要根据广度优先顺序图来找对应的super

例如以下程序:

class A:
    def func(self):
        print(‘A‘)
class B(A):
    def func(self):
        super().func()
        print(‘B‘)
class C(A):
    def func(self):
        super().func()
        print(‘C‘)
class D(B,C):
    def func(self):
        super().func()
        print(‘D‘)
d = D()
d.func()     #结果为 A-C-B-D

该程序分析过程如下:

【注】:supper(),在单继承中就是单纯的寻找父类,在多继承中就是根据子节点所在图的 mro 顺序找寻下一个类。

9,python 2中的经典类的多继承问题

【注】:经典类只在 python2 版本才存在,且必须不继承object。它在遍历的时候遵循深度优先算法,而且没有mro方法和super()方法。在python2 的版本中,必须手动继承object 类,才是新式类。它在遍历的时候遵循广度优先算法,在新式类中,有mro方法和super()方法,但是在2.X版本的解释器中,必须传参数(子类名,子类对象)。

【附】:python2 中的经典类中遵循的深度优先算法图示

原文地址:https://www.cnblogs.com/leiwei123/p/8809196.html

时间: 2024-10-01 03:01:17

面向对象的三大属性的相关文章

面向对象的三大特性

面向对象的三大特性: 封装, 继承, 多态 封装 封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节 继承: 子类拥有父类的属性和方法, 任何一个类都继承 Object (不管是java定义的还是自己定义的)::: Object.finalize()-->调用这个方法来释放资源: 多态(执行期间(执行期间-->你在控制台上写 java 类名 运行某个文件的时候叫执行期间)的动态绑定, 池绑定): 重载

面向对象的三大基石(封装,继承和复合,多态)

转自 面向对象的三大基石面向对象的三大基石(封装,继承和复合,多态) 三大基石之一 封装 1.什么是封装? 封装(encapsulation)又叫隐藏实现(Hiding the implementation).就是只公开代码单元的对外接口,而隐藏其具体实现. 比如你的手机,手机的键盘,屏幕,听筒等,就是其对外接口.你只需要知道如何按键就可以使用手机,而不需要了解手机内部的电路是如何工作的.封装机制就像手机一样只将对外接口暴露,而不需要用户去了解其内部实现.细心观察,现实中很多东西都具有这样的特点

Java面向对象的三大特点

Java面向对象的三大特点:继承.封装.多态 继承 继承的起源 使用“is a”关系判断继承 Java中继承的实现 关键字:extends 实例化子对象 单继承和多继承 子类继承父类.父类还可以继承上一个类,称为传递继承. Dog extends Animal: Animal extends ShengWu: 所有类的根类Object 即object类是所有类的父类,object中所有的方法其他类都可以直接调用 方法重写 父类方法   Public void jiao(){system.out.

php面向对象的三大特征

1.面向对象的三大特征:封装.继承.多态.(抽象(扩展的))2.00A:分析,OOD:设计,OOP:编程.3.封装:信息隐蔽,封装,所有的函数和方法,类中的属性和行为也是封装. 三个访问修饰符public.protected.private也是封装.4.public 公共的 谁都可以用,也可以修改:protected 受保护的 只有自己和后代可以使用和修改: private 私有的 只有自己可以使用和修改:5.继承: 扩展父类的内容,注意只能继承public和protected修饰的内容,而pr

面向对象设计三大特性

面向对象设计三大特性 一.封装 良好的封装能够减少耦合:类内部的实现可以自由地修改:类具有清晰的对外接口.比如建立一个猫的类,再建立一个狗的类,这样也算封装,只是会出现大量相似代码. 二.继承 继承的出现是因为对象类中出现过多重复代码,为解决该问题而建立父类,将这部分代码放进父类中,由子类继承.子类继承父类的所有特性,同时可以定义新的特性. 如果子类继承于父类,子类拥有父类非private的属性和功能:子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能:子类还可以以自己的方式实现父类的

面向对象的三大特征——封装、继承、多态

接触过面向对象的人都知道面向对象有三大特征,分别是封装.继承和多态.这三者分别指的是什么,为什么是这哥仨,使用他们有什么好处,我们来梳理一下. 封装 原则:隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处: ①将变化隔离. ②便于使用. ③提高重用性. ④提高安全性. Demo1: 比如一个学生类:他具有姓名和年龄两个属性,但是为了提高安全性和重用性,便于使用,我们将其封装起来. public class Student { private String name; private in

关情纸尾-----面向对象的三大特性

面向对象的三大特性 .封装 .继承 .多态 一.封装 1.set方法 (1)作用:提供一个方法给外界设置成员变量,可以在方法里面对参数进行过滤 (2)命名规范: 方法都是以set开头,而且后面要跟上成员变量名,成员变量名的首字母必须是大写 (3)形参名称不要和成员变量同名 (4)返回值一定是void (5)一定要接收一个参数,而且参数类型和成员变量类型一致 2.get方法 (1)作用:返回内部的成员变量 (2)命名规范:方法的名称一般就跟成员变量同名 (3)一定有返回值,并且返回值类型和成员变量

解析PHP面向对象的三大特征

class BenHang extends Card{ /*构造函数与及构造的继承*/ function __construct($cardno,$pwd, $name,$money){ parent::__construct($cardno,$pwd, $name,$money); } function take($money){ echo "本行取款{$money}没有手续费·····<br>"; } function zhuan($money){ echo "

聊一聊面向对象的三大特征

学习Java语言程序设计也有一段时间了.现在我想对封装.继承和多态,在Java中面向对象的三大特征,总结一下我的理解,不妥当的地方望大家包涵.  封装.给我的感觉封装就是一个包装,一个代码是否健壮,与用不用封装有很大的关系,封装就像是包裹一个礼物,不仅让礼物看起来更加精美,而且还完善了内容.请看代码: class Person {     private String name;     private int age;     public void say() {         Syste