面向对象的三大特征-----封装,继承和多态、特殊方法和属性

封装

可以提高程序的安全性。
将数据属性和行为方法包装袋类对象中。在方法内部对属性进行类对象的外部调用方法。这样无需关心方法内部的具体实现细节,从而减小复杂度。
可以从下面的例子可以看出

class Student:
    def __init__(self,name,age):
        self.name=name    ##定义了name和age两个实例属性
        self.__age=age    ##年龄age不希望在类的外部被使用,所以加了两个__
        '''
        age 不可以在外部使用,但是可以在;类的内部使用
        '''
    def show(self):
        print(self.name,self.__age)
stu1=Student('zhangsan',20)
stu1.show()
'''
如果在这里想输出年龄是不可以的
比如
print('stu1.__age')
程序是会报错的
'''
'''
但是想要输出年龄还是有办法的,qwq 笑死
有个办法
可以输入print(dir(stu1))
可以得到stu1可以调用输出的属性
print(stu1._Student__age)就可以输出年龄了
'''
print(stu1._Student__age)

继承

语句如下:

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

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): #创建子类 student类
    def __init__(self,name,age,stu_no): #多设置了学生号这个参数
        super().__init__(name,age)##使用这个语句来调用父类中的初始方法,即父类的构造方法
        self.stu_no=stu_no
class Teacher(Person):  #创建子类,Teacher
    def __init__(self,name,age,tea_no,teachofyear): #多设置了教职工号和教龄这个参数
        super().__init__(name,age)##调用父类的构造函数
        self.tea_no= tea_no
        self.teachofyear=teachofyear
tea=Teacher('zhangsan',50,2017211797,20)
stu=Student('lisi',20,2017211797)
tea.info()
stu.info()

方法重写

  • 如果子类对继承自父类的某个属性或方法不满意,可以在子类中对某个方法体进行重写
  • 子类重写后的方法中可以通过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): #创建子类 student类
    def __init__(self,name,age,stu_no): #多设置了学生号这个参数
        super().__init__(name,age)##使用这个语句来调用父类中的初始方法,即父类的构造方法
        self.stu_no=stu_no
    def info(self): #Student类进行对父类方法重写
        super(Student, self).info()
        print('学生的学号是:',self.stu_no)

class Teacher(Person):  #创建子类,Teacher
    def __init__(self,name,age,tea_no,teachofyear): #多设置了教职工号和教龄这个参数
        super().__init__(name,age)##调用父类的构造函数
        self.tea_no= tea_no
        self.teachofyear=teachofyear
    def info(self):  #Teacher 类进行对父类进行方法重写
        super(Teacher, self).info() #输出父类的结果
        print('该教师的教师工号是:',self.tea_no,'教龄为',self.teachofyear)
tea=Teacher('zhangsan',50,2017211797,20)
stu=Student('lisi',20,2017211797)
tea.info()
stu.info()

可以与上面没有进行方法重写的程序进行对比

object类(是所有类的父类)

dir(Student)#查看这个类所有的属性和方法
'''
可以看见很多属性和方法 这些都是从父类object那里继承过来的
'''

object类中有个函数 str(),用于返回一个对于‘’对象的描述‘’,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常对__str__()进行重写

class Student:
      def __init__(self,name,age):
          self.name=name
          self.age=age
      def __str__(self): ##str()方法进行重写
          print( '我的姓名是{0},今年{1}岁'.format(self.name,self.age)) ##这个格式记住就行了

stu=Student('zhangsan',20)


stu.__str__()

return ‘我的姓名是{0},今年{1}岁’.format(self.name,self.age)
上面这个格式记住就行了

多态

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

class Animal(object):
      def eat(self):
          print('动物吃东西')
class Dog(Animal):
      def eat(self):
          print('狗吃肉')
class Cat(Animal) :
      def eat(self):
          print('猫吃鱼')
class Person(object):
      def eat(self):
          print('人吃五谷杂粮')
def fun(animal):
    animal.eat()
    '''
    就是说person和animal之间没有继承关系,但是这个函数调用只要你有eat这个方法就行,就可以进行调用
    '''
fun(Dog())
fun(Person())
fun(Cat())

特殊方法和特殊属性

名称属性
特殊属性_dict_获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法_len_()通过重写__len__() 方法,让内置函数len()的参数可以是自定义类型
_add_()通过重写add()方法,可使用自定义对象具有‘’+‘’的功能
_new()_用于创建对象
_init_()对创建的对象进行初始化

##__dict__语句

class Student:
    def __init__(self,name):
        self.name=name
x=Student('jack')
print(x.__dict__) ##可以输出绑定的属性

##__bases__语句

class A:
    pass
class B:
    pass
class Student(A,B):   
    def __init__(self,name,age):
        self.name=name
        self.age=age
x=Student('jack',20)
print(x.__dict__) ##可以输出绑定的属性
print(Student.__bases__)## 可以输出Student的父类有哪些
print(Student.__mro__)##可以查看类的层次结构
print(A.__subclasses__())##查看A的子类

##_add_()语句

a=100
b=100
c=a+b
print(c)
d=a.__add__(b) ##对两个整数可以实现相加
print(d)
'''
现在看看他在类中函数的使用
'''
class Person:
    def __init__(self,name):
        self.name=name
    def __add__(self, other):  ##self,other都是系统自定义的参数
        return self.name+other.name
    '''
    
    这里相当于重写了add函数
    必须重写了add函数
    后续的方法一和方法二才能真的实现
    否则就会报错
    '''
stu1=Person('zhangsan')
stu2=Person('lisi')
print(stu1.__add__(stu2))##两个对象相加方法一 ##stu1代表self参数 ,进行传参,stu2代表other进行传参
s=stu1+stu2 ##两个对象相加方法二
print(s)
print(stu1.name+stu2.name) ##这个也是同理的 会更好理解一些

##_len_()语句

class Person:
    def __init__(self,name):
        self.name=name
    def __add__(self, other):  ##self,other都是系统自定义的参数
        return self.name+other.name
    '''
    
    这里相当于重写了add函数
    必须重写了add函数
    后续的方法一和方法二才能真的实现
    否则就会报错
    '''
stu1=Person('zhangsan')
stu2=Person('lisi')
print(stu1.__add__(stu2))##两个对象相加方法一 ##stu1代表self参数 ,进行传参,stu2代表other进行传参
s=stu1+stu2 ##两个对象相加方法二
print(s)
print(stu1.name+stu2.name) ##这个也是同理的 会更好理解

'''
下面是len语句的例子
'''
lst=[11,22,33,44]
print(len(lst)) ##输出列表长度
print(lst.__len__()) ##也是输出列表长度 ##__len__()这个就是内置函数
'''
在类中需要去重写这样一个len函数
'''
class Student(Person): #创建Student类继承Person类
    def __init__(self,name,stu_no): #重写init方法
       super().__init__(name) ##调用父类的方法

       self.stu_no=stu_no ##定义这个参数
    def __len__(self): ##多编写了一个len的方法
        return len(self.name) ,len(self.stu_no) ##
stu=Student('zhangsan','2017211797')
print(stu.__len__())

##_new_()语句

class Person:
    def __init__(self, name, age):
        print('__init__被调用了,self的id值为{0}'.format(id(self)))
        self.name = name
        self.age = age
    def __new__(cls, *args, **kwargs):  ##p1的person传给了new的cls
        print('__new__被执行调用了,cls的id值为{0}'.format(id(cls)))
        obj=super().__new__(cls) ##这里的person又传过来了,创建了对象obj
        print('创建的对象的id为{0}'.format(id(obj)))
        return obj ##返回的obj对象随后又传给了init



print('object这个类对象的id为{0}'.format(id(object)))
print('Person这个类对象的id为{0}'.format(id(Person)))

##创建Person类的实例对象
p1=Person('张三',20)
print('p1这个Person类的实例对象的id为{0}'.format(id(p1)))
'''
输出结果:
object这个类对象的id为8791489755984
Person这个类对象的id为65387984
__new__被执行调用了,cls的id值为65387984
创建的对象的id为83397456
__init__被调用了,self的id值为83397456
p1这个Person类的实例对象的id为83397456
'''
##由上述结果可以看出这个new创建的对象就是self和p1
##程序p1赋值,会先执行右侧的代码p1=Person('张三',20) 
##上面这一步就会将Person传给实例方法new的cls(即对象类型传给cls)
##创建obj然后返回 传个self 随后要赋给了p1
##虽然但是 也不知道为什么是这个流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值