飞道的博客

面向对象编程

448人阅读  评论(0)

面向对象

面向对象(oop) = object oriented programming

核心概念:

类: 是一群具有相同特征或行为的事物的统称,类是抽象的,不能直接使用,类是一个模板
对象: 由类创造出来的具体存在 类:
属性(信息)和方法(你能完成的事情)

例如
小明今年18岁,身高1.75,每天早上要跑步,跑完去吃饭
小美今年16岁,身高1.65,小美不跑步,喜欢吃东西
类是 people,属性是身高和年龄,方法就是跑步,吃饭

定义类,对象和实例化

1.如何定义类?class 类(): pass
2.如何将类转化为对象?实例化
实例化指在面向对象编程中,使用类创建对象的过程称为实例化,是将
一个抽象的概念具体化的过程
实例化过程:   对象名 = 类名(参数1,参数2,…)


我们先定义一个类:

class People():          #定义People类
    #s属性
    name = 'laoli'
    age = 40
    
    #方法             也是用def定义,但是称为方法,method
    def eat(self):             #self就是对象本身
        print('eat....')
        
    def sleep(self):
        print('sleep...')
p1 = People()             # p1,p2 都是对象
p2 = People()
print(p1.name)
print(p2.name)
p1.eat()
p2.eat()


可见使用这个类时所有的People都是 laoli ,这样的模板时锁死的,没有复用性,那么我们可以:
构造方法(初始化方法)

class People():
    def __init__(self):             不需要调用,在实例化对象时自动执行。
        print('self',self)

p1 = People()
print('p1',p1)


可见 self 就是 p1。

封装

封装也成信息隐藏,封装就是定义类的模板。把属性和方法封装到类中,用 self.修饰符 去调用就行了

class people():
    def __init__(self,name,age):   添加两个参数,实例化对象时没加参数会报错
        self.name = name       变量,(相当于把self和name封装在一起)
        self.age = age
    def __str__(self):             返回一句话
        return 'I am %s' %self.name

    def run(self):               定义函数
        print('%s is running' %self.name)
p1 = people('laoli',40)
print(p1.name)
p1.run()
print(p1)
p2 = people('laocao',99)
print(p2.name)
p2.run()
print(p2)


练习
“”"
需求
1.小明体重75.0公斤
2.小明每次跑步会减肥0.5公斤
3.小明每次吃东西体重会增加1公斤

需求
1.小明和小美都爱跑步
2.小美体重45.0公斤
3.小明体重75.0公斤
4.每次跑步都会减少0.5公斤
5.每次吃东西都会增加1公斤
“”"

class people():
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
    def __str__(self):
        return 'My name is %s,weight %.2f' %(self.name,self.weight)
    def run(self):
        print('%s is running..' %self.name)
        self.weight -= 0.5
    def eat(self):
        print('%s is eatting..' %self.name)
        self.weight += 1
xiaoming = people('xiaoming',75.0)
xiaoming.run()
print(xiaoming)
xiaomei = people('xiaomei',45.0)
xiaomei.run()
print(xiaomei)

封装栈

栈先进后出。

class Stackobject):
    def __len__(self):
        return len(self.stack)

    def top(self):
        if not self.is_empty():
            return self.stack[-1]
        raise Exception('stack is empty!')

    def push(self,element):
        self.stack.append(element)

    def pop(self):
        if self.is_empty():
            raise Exception('stack is empty!')
        else:
            item = self.stack.pop()
            return item

    def length(self):
        return len(self.stack)

    def is_empty(self):
        return len(self.stack) == 0

stack = Stack()
stack.push(1)
stack.push(2)
print(stack.stack)               查看栈
print(stack.length())            查看长度
print(stack.top())			     查看栈顶元素
item = stack.pop()               弹出
print('The pop is %s' %item)
print(stack.stack)
print(stack.is_empty())          是否为空

这样我们就可以用类把一个栈的功能封装起来。

栈和队列的区别:

栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
栈是先进后出,队列是先进先出。
栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除。

练习:
“”"
需求:
1.房子有户型,总面积和家具名称列表
新房子没有任何的家具

2.家具有名字和占地面积,其中
床:占4平米
衣柜:占2平米
餐桌:占1.5平米
3.将以上三件家具添加到房子中
4.打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表

“”"
定义两个类:

class Furniture(object):                   #家具类

    def __init__(self,name,area):
        self.name = name
        self.area = area

    def __str__(self):
        return '[%s] 占地 %.2f 平米' %(self.name,self.area)

# bed = Furniture('bed',4)
# print(bed)

class House(object):                    房子类

    def __init__(self,type,area):
        self.type = type
        self.area = area
        self.free_area = area
        self.fur_list = []

    def __str__(self):
        return ('户型: %s\n总面积: %.2f\n剩余面积: %.2f\n家具: %s'
                % (self.type, self.area, self.free_area, self.fur_list))

    def add_fur(self, item):
        self.fur_list.append(item.name)
        self.free_area -= item.area
bed = Furniture('bed',4)
yigui = Furniture('yigui',2)
table = Furniture('table',1.5)

home = House('villa',200)
home.add_fur(bed)
home.add_fur(yigui)

print(home)

继承

“”"
继承描述的是事物之间的所属关系,定义一个类时,可以从某哪个现有的类继承
新的类称为子类,扩展类(subclass),被继承的类称为基类、父类或超类(Baseclass、Superclass)

继承是面向对象重要的特征。继承是指在一个类基础上定义一个新类,原有的类叫做父类,新生成的类叫子类,继承的过程是一个从一般到特殊的过程。
“”"

class Father(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def eat(self):
        print('%s is eating...' %self.name)

    def set_goal(self):
        print('%s set a goal' %self.name)

class Son(Father):     括号内为父类

    def eat(self):
        # super(Son,self).eat()         用法同下一行
        Father.eat(self)   可以共同执行子类和父类的方法
        print('%s daoli eating...' %self.name)

father = Father('laolaoli',65)

son = Son('laoli',40)
print(son.name)
son.set_goal()
son.eat()

我们可以发现子类可以继承父类的属性和方法,当子类和父类出现了同名的方法是。会执行子类的方法。加上 Father.eat(self) 可以共同执行

多继承

python3 都是以 object 为基类的 python2 默认以经典类(旧式类)为基类


可见新式类的方法法比较多,所以推荐大家在定义类时用新式类,就是加上 object。例如:

class people()				旧式类
class people(object)       新式类

新式类都是广度优先,(python3)
旧式类都是深度优先 (python2)

class D():
    def test(self):
        print('test in D...')

class C(D):
    def test(self):
        print('test in C...')

class B(D):
    def test(self):
      print('test in B...')

class A(B,C):            #同时继承两个父类
    def test(self):
       print('test in A...')

ABC都是D的子类,
在A中找不到的方法就去父类B中找,找不到再去C中找,找不到再去D中找,这就是广度优先。



在A中找不到的方法去B中找,B中找不到就去D中找,这就是深度优先。

私有属性,私有方法

python中有一些代码是不能让外部访问,只有作者知道,叫做私有方法。

以双下划綫开头就是私有属性
以双下划线开头的函数就是私有方法。

class Student(object):

    def __init__(self,name,age):
        self.name = name
        self.__age = age      表示私有属性

    def __get_info(self):     表示私有方法
        print('%s is %s years old' %(self.name,self.__age))
        student1 = Student('xiaoming',10)
print(student1.name)
print(student1.__age)
student1.__get_info()


执行时报错,说没有__age 这个属性,这就是私有属性

同样方法也不存在。
但我们的python3中的解释器可以吧 __age 这个属性转化为 _类名__age , 我们可以通过这种方法进行调用。

#   print(student1.__age)
#   student1.__get_info()  

print(student1._Student__age)
student1._Student__get_info()


就执行出来了。

一个应用场景:当私有属性可被一个方法调用时:

class Student(object):

    def __init__(self,name,age):
        self.name = name
        self.__age = age           #私有属性

    def __get_info(self):		   #私有函数
        print('%s is %s years old' %(self.name,self.__age))

    def get_age(self):
        print(self.__age)

    def set_age(self,age):
        if 0 < age < 100:
            self.__age = age
            print('success!')
        else:
            raise Exception('Error!')

student = Student('xiaoming',10)
# student.__age = 100
# print(student.__age)
# student.__get_info()
student.get_age()
# student.set_age(20)


我们可以用命名变量的方式调用出来。

也可以通过一个非私有方法去调用私有方法。

多态

继承机制说明子类具有父类的公有属性和方法,而且子类可以扩展自身的功能,添加新的属性和方法。因此,子类可以替代父类对象,这种特性称为多态性。
此外,从根本上说,所谓多态性是指当不同的对象收到相同的消息时,产生不同的动作。
例如,Apple、Banana类继承了Fruit类,因此Apple、Banana具有Fruit类的共性。Apple、Banana类的实例可以替代Fruit对象,同时又呈现出各自的特性。

原文链接:https://blog.csdn.net/Homewm/article/details/78486158

多态性:

继承同一个类的多个子类中有相同的方法名

那么子类产生的对象就可以不用考虑具体的类型而直接调用功能
class Student():
    def get_score(self):
        print('Student score...')

class Chinese():
    def get_score(self):
        print('Chinese score...')

class Math():
    def get_score(self):
        print('Math score...')

student1 = Student()
student2 = Chinese()
student3 = Math()
student1.get_score()
student2.get_score()
student3.get_score()


使用同样的命令作用于不同的对象,得到不同的结果,这就是多态性。


转载:https://blog.csdn.net/thermal_life/article/details/105757096
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场