面向对象概述
前言
–写下本文的原因是为了加深印象,当然如果大家能从本文有所收获,对我来说就是最大的满足了。(╹▽╹)
知识目标
1、掌握面向过程与面向对象的概念
2、理解面向对象编程思想
3、掌握类和对象的概念
4、掌握面向对象设计基本步骤
能力目标
1、提高程序调试能力
2、培养发现问题、分析问题、解决问题的能力
3、培养自我管理与自主学习能力
一、面向对象是什么?
示例如上:请允许我用一张图表来表述
我们以往都是用面向过程的编程。例如:家里的灯坏了,你要去买灯、换灯等。
如今我们应该把思维转变过来。何为面向对象(Object)编程: 将数据与函数绑定到一起进行封装,关注的是解决问题需要那些对象,将通过调用对象实现。他的核心概念就是封装了属性和方法,以数据为中心,实现类类级别的代码重用。我们还是用灯坏了举例:灯坏了,找修理工维修。大家也可以思考一下其他的在此就不一一列举了。(^o^)
二、对象和类
接下来我们来谈谈对象和类先用一张图标来表示:
1、什么是类?
类是将具有共同特征和行为的一组对象抽象定义所提出的新概念,类是封装对象的属性和行为的载体。类是抽象的在使用的时候通常会找到这个类一个具体的存在。特别注意的是一个类可以找多个对象(ps:专一是最重要的!!!)
2、类与对象的关系
类相当于一个模板,对象就是依照次模板产生的产品,(如:汽车就是先设计出模型在开始制造的)。类是对某一类事物的具体描述;对象是实际存在的每个个体,因而也成实例(instance)。
定义类:class是声明类的关键字,“类名”是自定义的类名,采用大驼峰命名。类体的各个语句采用缩进方式表达他们是类中的语句。
语法格式: 引用对象的变量名=类名([参数列表])
3、创建对象和调用对象成员
对象必须通过类的创建获得,对象是一个具体的实实在在存在的事物,是数据和功能的集合。数据称之为对象的属性,功能称之为对象的方法。
属性对应变量,而方法对应函数。把数据和操作封装在一起,使程序结构清晰,这就是所谓的封装性.
4、使用属性
代码演示:
定义和调用方法
class Person: # 定义一个名字为person的类
pass # 站位
per = Person() # 创建person类的对象,赋值给per
per.name = "张三" # 添加属性name
per.age = 19
print(per.name) # 输出per的属性值
print(per.age)
per.age = 19
print(per.age) # 修改per对象的age属性值
class Person:
def show(self):
print("姓名:{},年龄:{},性别:{}".format(self.name, self.age, self.sex))
per = Person()
per.name = "张三"
per.age = 13
per.sex = "女"
per.show()
特别注意:
类的对象方法中存在特殊关键字self,表示当前对象,即调用该方法的对象。
在对象方法中可以通过self获取到调用该方法的对象,从而通过self操作对象上的属性和方法,利用self可以在方法中给对象定义属性
class Person:
def setSex(self, sex):
self.sex = sex # 通过self在类中定义属性sex
def show(self):
print("姓名:{},年龄:{},性别:{}".format(self.name, self.age, self.sex))
per = Person() # 创建person类对象per
per.name = "张三"
per.age = 13
per.sex = "女"
per.show() # 通过对象per调用show方法
ps:总结
对象就是描述客观食物的一个实体,由一组属性和方法构成。
类是具有相同属性和方法的一组对象的集合。
属性—对象具有的外在特征(静态属性),每个对象的每个属性都拥有特定的值.
方法–对象的内在行行为或具备的功能
插播:魔法方法
突然记起来的,老规矩咱们还是用一个图标来了解
知识目标:
1、了解魔术方法
2、掌握构造方法的使用
3、掌握__str__方法的使用
4、掌握析构方法的使用
01构造方法 _ _init _ _
构造方法是python类中的内置方法之一,名称固定,在类中定义,在创建一个类对象是会自动执行,负责完成创建对象的初始化工作。
··只有一个参数的构造方法示例:
class Person:
def __init__(self): # 定义构造方法
print("构造方法被调用!")
self.name = "未知"
self.age = 0
self.sex = "男"
def show(self): # 定义普通show方法
print("姓名:{},年龄:{},性别:{}".format(self.name, self.age, self.sex))
per = Person() # 创建person类对象per,自动执行构造方法
per.show() # 通过对象per调用show方法
··带默认参数的构造方法:
class Person:
def __init__(self, name="未知", age=0, sex="男"): # 定义构造方法
print("构造方法被调用!")
self.name = name
self.age = age
self.sex = sex
def show(self): # 定义普通show方法
print("姓名:{},年龄:{},性别:{}".format(self.name, self.age, self.sex))
per1 = Person() # 创建person类对象per,自动执行构造方法
per2 = Person("张三", 18, "女")
per1.show() # 通过对象per1调用show方法
per2.show() # 通过对象per2调用show方法
02_ _str _ _
直接print(object)打印对象,会看到创建对象在内存中的地址。
使用示例:
class Person:
def __init__(self, name="未知", age=0, sex="男"): # 定义构造方法
print("构造方法被调用!")
self.name = name
self.age = age
self.sex = sex
def __str__(self): # 定义魔法方法
msg = "姓名:{},年龄:{},性别:{}".format(self.name, self.age, self.sex)
return msg
per1 = Person() # 创建person类对象per,自动执行构造方法
per2 = Person("张三", 18, "女")
print(per1) # 输出per1对象,自动执行str方法
print(per2) # 输出per2对象,自动执行str方法
03_ _del _ _
构造方法是类的另一个内置方法,在销毁一个对象是会自动执行,负责完成待销毁对象的资源清理工作,如关闭文件。
演示:
class Person:
def __init__(self, name="未知", age=0, sex="男"): # 定义构造方法
print("构造方法被调用!")
self.name = name
self.age = age
self.sex = sex
print("姓名为{}对象被创建".format(self.name))
def __del__(self): # 定义魔法方法
print("姓名为{}的对象被销毁".format(self.name))
def func(name):
per = Person(name) # 创建Person类对象per
per1 = Person("张三") # 创建person类对象per,自动执行构造方法
per2 = Person("李四")
per3 = per2
del per2 # 使用del输出per2对象
func("王五") # 调用func函数
del per3 # 使用del输出per3对象
per4 = Person("赵六") # 创建Person类对象per4
per5 = Person("马奇")
per4 = "赵六" # 保存对象引用的变量被设置成其他的值
print("最后一行代码")
三、特别注意
说的就是你别想今天晚上该吃什么了,重点来了
晚点我会将三个特征用超链接方式放在下面。
面向对象的三个基本特征
1.封装
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类,类通常会对用户隐藏其实现的细节,这就是封装的思想。(ps:为什么要隐藏呢,假如你今天晚上吃最爱的鱼香肉丝,你会想这道菜怎么做的吗…咳咳··其实我会做的。emm 哈哈哈 你就这样理解就行了.)
话不多说,上图表:
知识目标:
1、掌握私有成员的使用
2、掌握getter/setter方法的使用
3、掌握私有成员的作用
01私有成员
python默认情况下属性和方法是公有的,可以在类的外部直接访问。
私有成员只能在定义其本类内部访问,而在类外无法直接访问。
(ps:在名称前加2个下划线‘__’,变成私有成员的属性或方法)
演示:
class Person:
def __init__(self, name="未知", age=0, sex="男"): # 定义构造方法
print("构造方法被调用!")
self.name = name
self.age = age
self.sex = sex
def __prepare(self): # 定义私有方法
print("化妆,换衣服")
return True
def show(self): # 定义一般方法
if self.__prepare(): # 调用私有方法
print("开始表演")
def __str__(self):
msg = "姓名:{},年龄:{},性别:{}".format(self.__name, self.__age, self.__sex)
return msg
per = Person("张三", 12, "女")
# print(per.sex) #报错,不能直接在类外访问私有属性
per.show()
# per.prepare() # 报错,不能直接在类外访问私有方法
在这个例子中,外界最终只关心人是否能够表演,并不关心除此之外的事物。所以将“准备工作”方法设置为私有方法__prepare()。
实际上,python中并不存在无法访问的所有成员。python没有严格意义上的封装,所谓的私有变量知识在形式上做出限制。
02getter/setter方法
示例:
class Person:
def __init__(self, name="未知", age=0, sex="男"): # 定义构造方法
print("构造方法被调用!")
self.name = name
self.age = age
self.sex = sex
def getSex(self): # 定义私有属性__sex的getter方法供外界访问私有属性
return self.__sex
def setSex(self, sex):
if sex == "男" or sex == "女":
self.__sex = sex
else:
self.__sex = '男'
per = Person("张三", 12, "女") # 创建对象per
per.setSex("天") # 调用setter方法修改__sex的值
print(per.getSex()) # 调用getter方法获取__sex的值输出
特别提醒:面向对象编程的思想关注的对象功能完成的结果,不关注内部实现和过程。
例如:ATM取款机,包含许多功能,但最终提供给用户的是取钱功能,其他都隐藏了,因为用户只关心取钱功能。
练习题
定义student类,包括属性学号、姓名、年龄、性别以及三门课程python、java、SQL成绩
计算总分、平均分、最高分、最低分。
class Student:
def __init__(self, id, name, age, score):
self.id = id
self.name = name
self.age = age
self.score = score
def getID(self):
return self.id
def getName(self):
return self.name
def getAge(self):
return self.age
def getScore(self):
print("%s %s的年龄%s python分数%s java分数%s sql分数%s 总分为%.2f 平均分%.2f 最高分%s 最低分%s" % (
self.id, self.name, self.age, self.score[0], self.score[1], self.score[2], sum(self.score),
sum(self.score) / len(self.score), max(self.score)
, min(self.score)))
stu1 = Student("21262002", "张三", "14", [39, 43, 54])
stu1.getScore()
2.继承
你可以这样理解:拓展父类得到子类,子类复用了父类的属性和行为的同时又添加了子类特有的属性和行为。继承是实现代码重用的主要手段。
上图:
1.知识目标:
1、掌握继承的概念和作用
2、掌握子类的定义
3、掌握多层继承的使用
4、了解多重继承
5、掌握方法的重写
6、掌握super方法的使用
关系图如下:
注意:子类会继承父类中定义的属性和方法,但不包含私有属性和私有方法。另外,在子类中可以增加新的属性和方法 。
2、示例
#子类定义示例--父类
class Person:
def __init__(self, name="未知", age=0): # 定义构造方法
self.name = name # 定义self对应对象的name属性赋值为形参name的值
self.age = age # 定义self对象对象的私有属性__age,并赋值形参age的值
def getAge(self): # 定义私有属性__age的getter方法
return self.__age
def setAge(self, age): # 定义私有属性__age的setter 方法
self.__age = age
def __drive(self): # 定义私有方法
print("{}会开车!".format(self.name))
def run(self): # 定义普通方法
print("{}在跑步!".format(self.name))
# 子类定义示例--子类
class Student(Person): # 以Person类作为父类定义类student
def study(self):
print("{}在学习!".format(self.name)) # 调用从父类继承下来的name
self.run() # 从父类继承下来的run方法
# print("{}岁".format(self.__age))#报错 子类不能继承父类的私有属性
print("{}岁".format(self.getAge()))
# self.__drive() #报错子类不能继承父类私有方法
stu = Student("张三", 18) # 创建子类对象stu
print(stu.name) # 通过stu对象调用从父类继承下来的name属性并输出
stu.run() # 通过stu对象调用从父类继承下来的run方法
stu.study() # 通过stu对象调用子类自己的study()方法
注意:类的定义方式有两种:新式类与经典类,class Person:经典类;class Person(object):新类,在任何时候,如果没有合适的类可以继承,就会继承字object类
3、其中继承分为三种继承:
1.单继承
:如果一个子类只有一个父类,称为单继承。
2.多层继承
:在继承关系中,子类可以拥有父类的功能,也可以有父类的父类的功能,即最后一个类继承前面这些类中的所有功能。
3.多重继承
:如果一个子类有两个或更多父类,称为多重继承。
演示:
class Animal(object):
def run(self):
print("Animal running")
class Cat(Animal):
def run(self):
print("猫咪咪在跑")
class Dog(Animal):
def run(self):
print("狗狗在跑")
animal = Animal()
animal.run()
a = Cat()
a.run() # 发生了多态
a = Dog()
a.run() # 发生了多态
4、方法重写:
指的是之类可以对父类中继承过来的方法进行重新定义,从而使得子类对象可以表现出父类对象不同的行为
演示:
class Person:
def __init__(self, name):
self.name = name
def printlnfo(self):
print("姓名:{}".format(self.name))
class Student(Person): # 以person类作为父类定义子类student
def __init__(self, sno, name): # 重写父类中的构造方法
self.sno = sno # 将self对象的sno属性赋值形参sno的值
self.name = name
def printlnfo(self): # 重写父类中的printlnfo方法
print("学号:{},姓名:{}".format(self.sno, self.name))
stu = Student("2718742965", "李四")
stu.printlnfo()
5、super方法
父类方法一旦被子类重写,子类对象就不会中的去找父类方法执行,在子类方法中可以通过super().父类方法名([实参列表])来调用被重写的父类方法。
# 父类
class Person:
def __init__(self, name):
print("person类构造方法碑额调用!")
self.name = name
def printlnfo(self):
print("姓名:{}".format(self.name))
# 子类
class Student(Person): # 以person类作为父类定义子类student
def __init__(self, sno, name): # 重写父类中的构造方法
print("Student类构造方法碑额调用!")
self.sno = sno # 将self对象的sno属性赋值形参sno的值
self.name = name
super().__init__(name) # 调用父类的构造方法
def printlnfo(self): # 重写父类中的printlnfo方法
print("学号:{}".format(self.sno, end=""))
super().printlnfo() # 调用父类中的printlnfo方法
stu = Student("265", "李四")
stu.printlnfo()
3.多态
将父类对象应用于子类的特征就是多态。即指父类中成员被子类继承之后,可以具有不同的状态或表现行为。
图来:
知识目标
1、了解多态的概念
2、了解鸭子类型
3、掌握isinstance、issubclass、type方法的使用
1、多态的概念
多态是指在执行相同代码情况下,根据对象所属类的不同去调用相应类的方法,从而执行不同效果。
两个前提:
1.继承----多态一定是发生在子类和父类之间;
2.重写----子类重写了父类的方法
示例
class Animal(object):
def run(self):
print("Animal running")
class Cat(Animal):
def run(self):
print("猫咪咪在跑")
class Dog(Animal):
def run(self):
print("狗狗在跑")
animal = Animal()
animal.run()
a = Cat()
a.run() # 发生了多态
a = Dog()
a.run() # 发生了多态
2、鸭子类型
示例
class Animal(object):
def sleep(self):
print("Animal running")
class Bird(Animal):
def run(self):
print("a bird sleeps in tree")
class Fish(Animal):
def run(self):
print("a fish sleeps in water")
class Person(Animal):
def run(self):
print("a Person sleeps in bed")
def goSleep(Animal):
Animal.run()
# goSleep(Animal())
goSleep(Fish())
goSleep(Person())
goSleep(Bird())
# animal = Animal()
# animal.run()
# a = Cat()
# a.run() # 发生了多态
# a = Dog()
# a.run() # 发生了多态
注意:鸭子类型语言中,函数可以接收一个任意类型的对象作为参数,只要该对象实现了代码后续用到的属性和方法就不会报错
3、内置函数(isinstance、issubclass、type)
四、编程练习
本文注重意会,剩余的部分我是真的心有力而力不足。所以还是要靠大家了(^U^)ノ~YO
五、总结
收尾呼应,最后还是用这个图表来结束吧(ps:你以为我会告诉你们我是懒得写才不写的吗)╭(╯^╰)╮
注:本文内容是对老师上课的总结,图标来自ppt,写本文的目的也是为了加深总结对于python面向对象的印象。当然如果这篇文章对您有所帮助,请一键三连(^U^)ノ~YO 拜谢~~~~~~~~~~~~~~~~