Python中的类和对象(二)

面向对象的三大特征:

封装:提高程序的安全性

        ·将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行赋值。在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而降低程序复杂度。

        ·在Python中没有专门的修饰符用于属性的私有,如果访问,前边使用两个'_'。

继承:提高代码的复用性

多态:提高程序的可扩展性和可维护性

1、封装

class Car:
    def __init__(self,brand):
        self.brand=brand
    def start(self):
        print('嘟嘟嘟嘟!汽车启动!')


car=Car('BMWX5')
car.start()#嘟嘟嘟嘟!汽车启动!
print(car.brand)#BMWX5

使用__(两个_)使属性无法在外部被访问

但还是可以使用stu1._Student__age来访问

因此Python中的私有就得靠程序员的自觉了

class Student:
    def __init__(self,name,age):
        self.name=name
        self.__age=age  #年龄不希望在类的外部被使用,所以加了两个_

    def show(self):
        print(self.name,self.__age)

stu1=Student('张三',20)#
stu1.show()#张三 20
#在类的外部访问name和age
print(stu1.name)#张三 20
#使用__修饰,无法访问age
#print(stu1.age) AttributeError: 'Student' object has no attribute 'age'
print(dir(stu1))
print(stu1._Student__age)#20   在类的外部可以通过 _Student__age访问

2、继承

单继承:

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def info(self):
        print(f'姓名:{self.name},年龄:{self.age}')
#定义子类
class Student(Person):
    def __init__(self,name,age,score):
        super().__init__(name,age)
        self.score=score

class Teacher(Person):
    def __init__(self,name,age,teachofyear):
        super().__init__(name,age)
        self.teachofyear=teachofyear

#测试
stu=Student('张三',20,100)
stu.info()#姓名:张三,年龄:20
teacher=Teacher('李四',30,10)
teacher.info()#姓名:李四,年龄:30

多继承:

class A(object):
    pass

class B(A):
    pass

#同时继承两个类
class C(A,B):
    pass

3、方法重写

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def info(self):
        print(f'姓名:{self.name},年龄:{self.age}')
#定义子类
class Student(Person):
    def __init__(self,name,age,score):
        super().__init__(name,age)
        self.score=score

    #重写info方法
    def info(self):
        super().info()#调用父类info方法
        print(f'成绩:{self.score}')

class Teacher(Person):
    def __init__(self,name,age,teachofyear):
        super().__init__(name,age)
        self.teachofyear=teachofyear

        # 重写info方法
    def info(self):
        super().info()  # 调用父类info方法
        print(f'教龄:{self.teachofyear}')

#测试
stu=Student('张三',20,100)
stu.info()#姓名:张三,年龄:20
         # 成绩:100

tea=Teacher('汪汪汪',30,10)
tea.info()#姓名:汪汪汪,年龄:30
         # 教龄:10

 4、object类

__str__方法类似于Java中的toString()方法

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '我的名字是{0},今年{1}岁'.format(self.name,self.age)

stu=Student('张三',20)
print(dir(stu))#['__class__'................]  从object中继承的
print(stu)#未重写方法之前:<__main__.Student object at 0x02F89770>
#重写方法之后  我的名字是张三,今年20岁
print(type(stu))#<class '__main__.Student'>

5、多态

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(Person())#人吃一切

Java就是静态语言,必须明确继承关系

而Python不关心这些,它关心的是有没有这个行为

6、特殊方法和特殊属性

类中的一些特殊属性

class A:
    pass

class B:
    pass

class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age

#创建C类的对象
x=C('Jack',20) #x是C类的一个实例对象
#__dict__获得类对象或实例对象所绑定的所有属性和方法的字典
print(x.__dict__)#{'name': 'Jack', 'age': 20}
print(C.__dict__)#{'__module__': '__main__', '__init__': <function C.__init__ at 0x00B2D270>, '__doc__': None}
print('------------')
#__class__输出对象所属的类
print(x.__class__)#<class '__main__.C'>
#__bases__输出的是类的父类类型的元组
print(C.__bases__)#(<class '__main__.A'>, <class '__main__.B'>)
#__base__输出的是第一个基类
print(C.__base__)#<class '__main__.A'>
#__mro__查看继承的层次结构
print(C.__mro__)#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
#__subclasses__查看所有的子类列表
print(A.__subclasses__())#[<class '__main__.C'>]

类中的特殊方法:

a=20
b=100
c=a+b#两个整数类型的对象的相加操作
d=a.__add__(b)
print(c)#120
print(d)#120

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('李四')
'''
TypeError: unsupported operand type(s) for +: 'Student' and 'Student'
未写__add__前报错

重写完__add__方法后的结果为:
张三李四
'''
s=stu1+stu2
print(s)
print('-----------------------')
lst=[11,22,33,44]
print(len(lst))#len是内置函数 ,可以计算列表的长度
print(lst.__len__())
#想要输出一个对象的长度,得先编写__len__()方法
'''
重写__len__方法前TypeError: object of type 'Student' has no len()
重写后:4

'''
print(len(stu1))

__new__与__init__

·__new__用于创建对象

·__init__用于对创建的对象进行初始化

执行顺序:

person=Person('张三',20)

先执行Person('张三',20)然后转入__new__函数,将Person对象传给cls,然后调用父类方法创建obj对象,最后返回obj对象。

obj对象作为__init__函数中的self传入,执行初始化方法后传给person

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值