Python(二十一):面向对象的三大特征


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

封装

  • 一般封装的属性前面会带有两个下划线

例:

class Student:
    def __init__(self,name,age):
        self.name=name
        self.__age=age#年龄不希望在类的外部被使用,所以前面加了两个下划线
    def show(self):
        print(self.name,self.__age)
stu=Student('张三',20)
stu.show()

#在类的外部使用name和age
print(stu.name)
print(stu._Student__age)#在类的外部可以通过  _类名__封装属性 进行访问

结果:

张三 20

张三

20

如果直接访问stu.__age程序会报错

继承

语法格式:

class 子类类名(父类1,父类2…):
(缩进)pass

  • 如果一个类没有继承任何类,则默认继承object
  • Python支持多继承
  • 定义子类时,必须在其构造函数中调用父类的构造函数

例:

class Person(object):#person继承object类
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def info(self):
        print( self.name,self.age)
class student(Person):
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)#super()继承父类的name、age
        self.stu_no=stu_no
class teacher(Person):
    def __init__(self,name,age,teacherfyear):
        super().__init__(name,age)
        self.teacherfyear=teacherfyear

stu=student('zz',18,5)
t=teacher('ss',34,10)
stu.info()
t.info()

结果:

zz 18

ss 34

方法重写

  • 如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其进行重写编写
  • 子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法

例:

class Person(object):#person继承object类
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def info(self):
        print( self.name,self.age)
class student(Person):
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)#super()继承父类的name、age
        self.stu_no=stu_no
    def info(self):#方法重写
        super().info()#先提供父类当中的info(),在调用子类当中的输出
        print('学号为:',self.stu_no)

stu=student('zz',18,5)
stu.info()

结果:

zz 18

学号为: 5

object类

  • object类是所有类的子类,因此所有类都有object类的属性和方法
  • 内置函数dir()可以查看指定对象的所有属性
  • Object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常
  • 用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写

例:

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):#重写str的方法,用于描述
        return '我的名字是{0},今年{1}岁'.format(self.name,self.age)
stu=Student('张三',20)
print(dir(stu))#查看stu所具有的属性
print(stu)

结果:

[‘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’, ‘age’, ‘name’]

我的名字是张三,今年20岁

多态

  • 简单的说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,
  • 仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法

例:

class Animal:
    def eat(self):
        print('动物能吃')
class Dog(Animal):
    def eat(self):
        print('狗吃骨头...')
class cat(Animal):
    def eat(self):
        print('猫吃鱼...')
class person:
    def eat(self):
        print('人吃五谷杂粮')
def fun(obj):#定义一个函数
    obj.eat()
fun(cat())
fun(Dog())
fun(Animal())
fun(person())

结果:

猫吃鱼…
狗吃骨头…
动物能吃
人吃五谷杂粮

特殊方法和特殊属性(全部是双下划线)

特殊属性:

  • dict:获得类对象或实例对象所绑定的所有属性和方法的字典

例:

class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age
x=C('jack',20)
print(x.__dict__)#实例对象的属性字典
print(C.__dict__)#类对象的属性字典
print(x.__class__)#输出实例对象所属的类
print(C.__bases__)#类的所有基类
print(C.__base__)#类的第一个基类
print(C.__mro__)#输出的是类层次结构
print(A.__subclasses__())#子类的列表

结果:

{‘name’: ‘jack’, ‘age’: 20}

{‘module’: ‘main’, ‘init’: <function C.init at
0x000001DF7D02CD30>, ‘doc’: None}

<class ‘main.C’>

(<class ‘main.A’>, <class ‘main.B’>)

<class ‘main.A’>

(<class ‘main.C’>, <class ‘main.A’>, <class ‘main.B’>,<class ‘object’>)

[<class ‘main.C’>]

特殊方法(有括号)

  • len():通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
  • add():通过重写__add__()方法,可使用自定义对象具有“+”功能

例:

class Student:
    def __init__(self,name):
        self.name=name
    def __add__(self,other):#实现了两个对象的加法运算
        return self.name+other.name
    def __len__(self):
        return len(self.name)
stu1=Student('张三')
stu2=Student('李四')
s=stu1+stu2#如果没有def __add__(self,other)函数输出结果s会报错
print(s)
m=stu1.__add__(stu2)#让两个对象相加的第二种写法
print(m)
print(len(stu1))#没有def __len__方法的话,会报错
print(stu1.__len__())#第二种得到对象长度的方法

结果:

张三李四

张三李四

2

2

  • new():用于创建对象
  • init():对创建的对象进行初始化
  • new()方法在__init__方法执行之前先进行创建对象

类的赋值

只是形成两个变量,实际上还是指向同一个对象
例:

class CPU:
    pass
cpu1=CPU()
cpu2=cpu1
print(cpu1)
print(cpu2)#cpu1与cpu2内存地址相同
结果:
<__main__.CPU object at 0x000001D3677DCFA0>
<__main__.CPU object at 0x000001D3677DCFA0>

(此时两个变量的内存地址为同一个)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值