Day12 面向对象的三大特性

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

1、封装

(1)类的封装特征 

隐藏对象的属性和实现细节,只对外提供必要的方法。
通过“私有属性、私有方法”的方式,实现“封装”。Python 追求简洁的语法

class game:
    def __init__(self,type):
        self.type=type   #type是类对象中的一个实例属性
    def start(self):
        print('正在启动游戏......,启动成功')

'''上面写到的方法都被包在game类里面,都隶属与game类,这就叫做封装'''
game1=game('动作冒险')
game1.start()
print(game1.type)

一开始类中的方法被打包在了类里面,这就叫做封装;后面使用了类当中封装包装的属性和方法

(2)若某个属性不想被该类对象外部访问,则在前面加两个'_'

class Students:
    def __init__(self,name,age):
        self.name=name
        self.__age=age     #不想让外部访问
    def process(self):
        print('该应用在半小时内禁止被访问')

stu1=Students('张三',20)
print(stu1.name)
print(stu1.__age)  #AttributeError: 'Students' object has no attribute '__age'  
'''在Students对象中没有找到age这个属性   因为代码遇到__age时程序就知道这个变量不能被外部使用'''

(3)虽然可以限制对象不被外部访问,但这只是我希望的情况,但实际上这个对象还是可以被使用,通过过dir()方法可以找到能使用对象的类似对象名

print(dir(stu1))

['_Students__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__le__', '__lt__', 
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'name', 'process']

在这一大堆结果里面,'_Students__age'这个对象名的效果就跟age一样,可以被使用,并且两者的结果都是一样的

print(stu1._Students__age)  #20

总结:已经被设置了不被外部访问的变量,在外部仍可以通过‘_类名__被限制外部访问的变量名’进行访问

封装的意义全靠自己自觉,看到变量限制访问了你就别去用了,完全靠自觉性 

2、继承

  在Python中支持多重继承,一个子类可以继承多个父类。继承语句的写法格式如下:

    class 子类类名(父类类名1,父类类名2......)

           类体

如果在类定义中没有指定父类,则默认父类是 object 类。也就是说,object 是所有类的父
类,里面定义了一些所有类共有的默认实现,比如:__new__()。

在刚开始学习类和对象的时候,在写完类名后都没有跟括号,代表着他们都使用的默认继承object

再上图的树状图中,从上到下他们依次具有继承的关系 

在子类中使用super().方法调用父类所构造的函数  格式:super().方法名

对继承的详细解释参考下文

python继承(super()、多继承、钻石继承)_patrick_wang_bigdata的博客-CSDN博客icon-default.png?t=M666https://blog.csdn.net/qq_23120963/article/details/105452376

(1)单继承:代码如下:

#定义父类
class Bookstore(object):   #Person继承默认object类
    def __init__(self,bookname,order):
        self.bookname=bookname
        self.order=order
    def Book(self):
        print(self.bookname,self.order)
        print('欢迎小主光临寒舍,请随意看看,祝您消费愉快')

#定义子类
class Book(Bookstore):    #继承的是父类Bookstore
    def __init__(self,bookname,order,type):
        super().__init__(bookname,order)
        self.type=type

#定义第二个子类
class people(Bookstore):
    def __init__(self,name,bookname,order,time):
        super().__init__(Bookstore)
        self.name=name
        self.time=time

book=Book('百科全书',2,'冒险')
person=person('张三','维基词典',2,20190101)

book.info()
person.info()

百科全书 2
欢迎小主光临寒舍,请随意看看,祝您消费愉快
维基词典 2
欢迎小主光临寒舍,请随意看看,祝您消费愉快

继承关系

  (2)多继承:

class A(object):
    pass
class B(object):
    pass
class C(A,B):
    pass

(3)方法重写 

子类想要输出自己独有的东西(变量),父类不能满足子类自身的需求,那么子类就学要重写方法

  在子类中重新定义一个方法,左面就会出现一个向上的箭头,写明Overrides method in 父类名,意思为重写父类名中的方法;同时在父类名左面也会出现一个向下的箭头,意思为该父类方法在某个子类中被重写过

 子类出现的提示

父类出现的提示

在上面继承那一块的代码上加做修改,就可以得到下面的代码

class Bookstore(object):   #Person继承默认object类
    def __init__(self,bookname,order):
        self.bookname=bookname
        self.order=order
    def info(self):
        print(self.bookname,self.order)
'''Bookstore这个父类同时被Book类和person类方法重写'''

#定义子类
class Book(Bookstore):    #继承的是父类Bookstore
    def __init__(self,bookname,order,type):
        super().__init__(bookname,order)
        self.type=type
      #重写方法
      #子类中想要输出自己独有东西,而父类不能满足,则需要对父类重写方法,重新定义一个方法
    def info(self):
        #在重写的过程中还想使用父类方法中的方法提,只需要调用即可,使用super().方法名的方式进行调用
        super().info()
        print('书的类型为:',self.type)
1
#定义第二个子类
class person(Bookstore):
    def __init__(self,name,bookname,order,time):
        super().__init__(bookname,order)
        self.name=name
        self.time=time
    #重写方法
    def info(self):
        super().info()
        print('购买时间为{0}'.format(self.time))

book=Book('百科全书',2,'冒险')
person=person('张三','维基词典',2,'2019年10月25日')

book.info()
person.info()

百科全书 2
书的类型为: 冒险
维基词典 2
购买时间为2019年10月25日

3、多态

以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数(面向对象的方法中一般为多态性):向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为,这样就会输出不同的信息

即使类和类之间类型不同,但里面有着相同的方法。不同的对象,调用相同的方法,产生不同的执行结果,增加代码的灵活度

(1)多态的特点:

  • 多态可以增加代码的灵活度
  • 以继承和重写父类方法为前提
  • 是调用方法的技巧,不会影响到类的内部设计

(2)实例代码

class Animal(object):
    def eat(self):
        print('动物爱吃的东西')
class Dog(Animal):  #Dog类继承Animal类
    def eat(self):
        print('狗吃骨头...')
class Cat(Animal):   #Cat类继承Animal类
    def eat(self):
        print('猫吃鱼...')

class person:   #没有继承任何类,只默认继承object类
    def eat(self):
        print('人吃五谷杂粮,鱼肉海鲜')

'''在外部定义一个函数fun()'''
def fun(anyobject):   #随便往函数里传一个对象
    anyobject.eat()

fun(Dog())
fun(Cat())
fun(Animal())
print('------------------------')
fun(person())   #person类与其他类没有继承关系,但person中有eat方法,所以也会调用person里面的eat方法

狗吃骨头...
猫吃鱼...
动物爱吃的东西
------------------------
人吃五谷杂粮,鱼肉海鲜

(3)“鸭子类型”

“鸭子类型”的程序不会检查对象的类型,只要你这个类里有所你调用的方法,就可以被正确的调用

就比如说上面的代码,fun()函数可以接受任意一个类型的对象(就是类),并且调用eat方法,它不关心你调用的是谁,它只管心这个对象里面有没有我需要被调用的对象

有一个函数调用Dog类,并利用到了方法eat()。我们传入Person类也一样可以运行,函数并不会检查对象的类型是不是Dog/Cat/Animal,只要他拥有eat()方法,就可以正确的被调用

 鸭子类型的几个简单代码实现

python什么是鸭子类型_杰森斯坦森1150的博客-CSDN博客_python鸭子类型https://blog.csdn.net/guiyin1150/article/details/122313754


浅谈python中的多态_python_脚本之家 (jb51.net)https://www.jb51.net/article/214923.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值