面向对象知识点1

面对对象编程的特点

继承

​ 在 OOP 程序设计中,当我们定义一个 class 的时候,可以从某个现有的class 继承,新的 class 称为子类(Subclass),而被继承的 class 称为基类、父类或超类(Base class、Super class)。Python当中,父类,子类(派生类),父类和子类只有在继承时才会产生。

​ 继承的优点就是子类可以轻而易举获得父类的所有属性,即减少代码的重复。

#以Animal为父类,People为Animal的子类
class Animal():
    def __init__(self, height, weight):
        self.height = height
        self.weight = weight
        
class People(Animal):
    pass

wq = People(170,140)
print(wq.height,wq.weight)	#170	140


#继承后,子类的属性查找先从子类的对象属性中找—子类的函数方法—父类—父类的父类

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):  # self = b
        print('Foo.f2')
        self.f1()  # b.f1()


class Bar(Foo):
    def f1(self):
        print('Bar.f1')


b = Bar()
print(b.__dict__)  # {}
b.f2()  # Foo.f2
		# Bar.f1

类的派生

​ 其实就是子类在继承父类所有的属性和函数方法时,自己拥有的独特的属性和方法,派生就是如何绑定这些独特的属性和函数方法。

#第一种方法:已经脱离了继承的本质,无需继承即可以获得父类的属性和函数方法
class Animal():
    def __init__(self, height, weight):  
        self.height = height  
        self.weight = weight
        
class People:
    def __init__(self.name,age,height,weight):
        Animal.__init__(self,height,weight)
        self.name = name
        self.age = age
        
wq = People('wnagqiang,25,175,130')

#第二种方法:必须通过继承父类
class Animal():
    def __init__(self, height, weight):  
        self.height = height  
        self.weight = weight
        
class People(Animal):
    def __init__(self.name,age,height,weight):
        super().__init__(height,weight)       #其实是对第一种方法的数据封装
        
        #super(People,self).__init__(height,weight)		#python2中的写法
        
        self.name = name
        self.age = age
        
wq = People('wnagqiang,25,175,130')

print(wq.__dict__)  #可以通过报错获知属性个数

​ 派生的和关键问题就是弄清楚对象属性的个数以及属性的查找

类的组合

#简单的选课系统

class People:
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender

class Student(People):
    def __init__(self,name,id,gender):
        super().__init__(name,gender)
        self.id = id

    def choose_course(self,course):
        
        **self.course = course**       
 #即通过类的函数对象(引用、返回值,参数)达到类的组合效果     
        return '%s选课%s成功'%(self.name,course.name)

class Teacher(People):
    def __init__(self,name,level,gender):
        super().__init__(name,gender)
        self.level = level

    def scored(self,student,course,score):
        return '%s老师给%s学生%s课程打分:%s'%(self.name,student.name,course.name,score)

class Course:
    def __init__(self,name,price):
        self.name = name
        self.price = price

class Admin(People):

    def create_course(self,name,price):
        course = Course(name,price)


        print('管理员%s创建课程%s'%(self.name,name))
        return course


#学生
s1 = Student('wangqiang','123','male')
s2 = Student('liujin','124','female')

#老师
t1 = Teacher('nick','0','female')

#管理员
a1 = Admin('sb','eunuch')

#业务逻辑

#1.创建课程
course1 = a1.create_course('python',20000)  #管理员sb创建课程python
course2 = a1.create_course('linux',18000)   #管理员sb创建课程linux

#2.学生选择课程
print(s1.choose_course(course1))
print(s2.choose_course(course2))

#3.老师打分
print(t1.scored(s1,course1,99))     #nick老师给wangqiang学生python课程打分:99

菱形继承问题

​ 在python3当中会默认继承object类,新式类:只要继承了object类的就是新式类,python3当中所有的类都是新式类。

​ 在python2当中不会默认继承object类,必须得自己手动添加,经典类:没有继承object类的就是经典类, 只有python2当中有经典类。

​ 当继承为菱形继承的时候:在新式类中:当遇到菱形继承时,会以广度优先查找

​ 在经典类中:当遇到菱形继承时,会以深度优先查找

类的多态与多态性

​ 当子类和父类都存在相同的 run()方法时,我们说,子类的 run()覆盖了父类的 run(),在代码运行的时候,总是会调用子类的 run()。这样,我们就获得了继承的另一个好处:多态。

#鸭子类型:子类和父类中都有相同的函数名,当定义一个类的调用函数时,只需要传入类名即可,无需实例
class People:
    def sleep(self):
        print('p is sleeping!')


class Animal:
    def run(self):
        print('animal is running!')

class Dog(Animal):
    def run(self):
        print('dog is running!')

class Cat(Animal):
    def run(self):
        print('cat is running!')

#调用类的定义函数
def run_twice(self):
    self.run()

#只需要传入类名()即可调用类中的函数方法
run_twice(Animal())	#animal is running!

run_twice(Dog())	#dog is running!

run_twice(Cat())	#cat is running!

posted @ 2019-06-23 22:19  wanjiang  阅读(114)  评论(0编辑  收藏  举报