《编程导论》8.1-8.22 类和继承(辅助学习的笔记~)

下面都是我今天学习了类和继承的内容和一些学习笔记,有在学习这本书的小白同党可以看下方便更好地理解哈~

#8.1_Person类

import datetime

class Person(object):

    def __init__(self, name):
        """创建一个人"""
        self.name = name
        try:
            lastBlank = name.rindex(' ')#rindex反向索引的下标
            self.lastName = name[lastBlank+1:]
        except:
            self.lastName = name
        self.birthday = None

    def getName(self):
        """返回这个人的姓名"""
        return self.name

    def getLastName(self):
        """返回这个人的姓"""
        return self.lastName

    def setBirthday(self, birthDate):
        """假定birthDate是datetime.date类型
            把birthDate设定为这个人的生日"""
        self.birthday = birthDate

    def getAge(self):
        """返回这个人的当前年龄对应的天数"""
        if self.birthday == None:
            return ValueError
        return (datetime.date.today() - self.birthday).days

    def __lt__(self, other):#重载了<操作符
        #当<的第一个参数是Person类型时,Person.__lt__会被调用
        """如果这个人的名字字典序列小于另一个人的名字返回True,否则返回False"""
        if self.lastName == other.lastName:
            return self.name < other.name
        return self.lastName < other.lastName

    def __str__(self):#__str__方法规范了输出格式
        #如果没有该方法print会输出<__main__.Person object at XXXXXXX>生成器格式
        """返回这个人的名字"""
        return self.name

me = Person('Michael Guttag')
him = Person('Barack Hussein Obama')
her = Person('Madonna')
print(him.getLastName())
him.setBirthday(datetime.date(1998, 10, 27))
her.setBirthday(datetime.date(1998, 11, 13))
print(him.getName(), 'is', him.getAge(), 'days old')

pList = [me, him, her]
for p in pList:
    print(p)
pList.sort()
for p in pList:
    print(p)



#8.2_Inheritance(继承)

class MITPerson(Person):#该类型是Person的子类,而Person是object的子类
    #子类会继承所有父类的属性

    nextIdNum = 0 #这就是类变量,有点类似于全局变量,这里作为身份证号

    def __init__(self, name):
        Person.__init__(self, name)
        self.idNum = MITPerson.nextIdNum #实例变量
        MITPerson.nextIdNum += 1

    def getIdNum(self):
        return self.idNum

    def __lt__(self, other):
        return self.idNum < other.idNum

    def isStudent(self):
        return isinstance(self, Student)
        #第一个参数为任意对象,第二个参数为type类型的对象
        #当且仅当第一个参数是第二个的实例时,返回True
    
p1 = MITPerson('Barbara Beaver')
print(str(p1) + '\'s id number is ' + str(p1.getIdNum()))
#在子类实例调用中,会首先检查子类的方法,如无再检查父类的方法

p1 = MITPerson('Mark Guttag')
p2 = MITPerson('Billy Bob Beaver')
p3 = MITPerson('Billy Bob Beaver')
p4 = Person('Billy Bob Beaver')

print('p1 < p2 =', p1 < p2)#明显的类变量和实例变量的区别
print('p3 < p2 =', p3 < p2)#每一个实例的创建,idNum都会+1,所以p2和p3会有区别
print('p4 < p1 =', p4 < p1)#<操作符通过第一个参数的类型决定调用哪个__lt__方法
#如p4 < p1,由于p4是Person类的,因而使用名字进行排序
#而p1是子类,继承了父类,因而也可以用名字排序

#print('p1 < p4 =', p1 < p4)
#调用p1的__lt__方法,但是p4作为父类并没有子类的__lt__方法,因而抛出异常



#8.2.1_MultilayerInheritance(多层继承)

class Student(MITPerson):
    pass

class UG(Student):

    def __init__(self, name, classYear):
        MITPerson.__init__(self, name)
        self.year = classYear

    def getClass(self):
        return self.year

class Grad(Student):
    pass

p5 = Grad('Buzz Aldrin')
p6 = UG('Billy Beaver', 1984)
print(p5, 'is a graduate student is', type(p5) == Grad)
print(p5, 'is an ungraduate student is', type(p5) == UG)

print(p5, 'is a student is', p5.isStudent())
print(p6, 'is a student is', p6.isStudent())
print(p3, 'is a student is', p3.isStudent())
#注意,isinstance(p6, Student)和type(p6) == Student是不同的
#p6是UG类型的对象,UG是Student的子类,因此p6也是Student的实例,但却不是此类型

#当然,由于只有两类学生,所以也可以这样实现:
#def isStudent(self):
    #return type(self) == Grad or type(self) == UG
#这样的缺点在于添加新的学生类型时需要修改isStudent,并且十分累赘
#而这个中间类Student并用isinstance内建函数则避免了这个问题

#如添加以下类:
class TransferStudent(Student):

    def __init__(self, name, fromSchool):
        MITPerson.__init__(self, name)
        self.fromSchool = fromSchool

    def getOldSchool(self):
        return self.fromSchool
#这样设计程序十分的有利于程序的开发和维护

#8.2.2_里氏替换原则/替代法则
#可以看这里https://blog.csdn.net/hdhai9451/article/details/45110397

里氏替换原则是我最看不懂的一个东西,但是看了这位大神的文章感觉理解还算行了一点点,但是也就只可意会不可言传的蹩脚程度啦,大家还是自行理解吧~(狗头)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值