Python学习之——面向对象 面向对象 类 对象 消息与方法 对象的三个内置方法 总结 面向对象的三大特征  


  • 概述:
    • 面向对象——Object Oriented
    • 理念——将真实世界的事物模块化
    • 优势——提供软件的可重用性、可读性
    • OOA——Object Oriented Analysis
    • OOD——Object Oriented Design
    • OOP——Object Oriented Program

  • 具有相同或相似性质的对象的抽象就是类
  • 对象的抽象是类,类的实例化就是对象
  • 类的属性——对象状态的抽象,用数据结构来描述
  • 类的操作——对象行为的抽象,用操作名和实现该操作的方法来描述
  • 一个类定义完,只有创建了该类的对象后,这个类才有意义
  • 在类的内部给对象添加属性(init)

类的结构

客观世界有若干类,类之间有一定的结构关系

  • 整体——部分:组装结构,与的关系
  • 一般——具体:分类结构,或的关系

类的定义

class 类名 [可选参数]:
	定义初始化内容
	定义初始化方法
  • class创建类的关键字
  • 类名:遵守标识符的命名规则
  • 方法:自定义函数

对象

  • 进行研究的任何事、物——具体的事物或抽象的规则、计划、事件
  • 对象的状态——用数据值来描述状态
  • 对象的行为——用操作来改变对象的状态
  • 对象实现了数据与操作的结合
  • Python在创建一个对象时
    • 会自动给这个对象在内存中分配存储空间
    • 会自动执行初始化函数init
    • init专门为对象添加属性的方法,初始化属性的方法
    • 当一个对象不再使用时,使用del()方法进行销毁
    • Python解释器会自动执行del()方法
  • 一般在输出对象变量时,会输出对象变量在内存的地址
  • 在输出对象变量时,使用str()方法输出特定的信息
    • str()方法必须返回一个字符串
  • __xxx__()这样的函数为内置函数

面向对象的特征

  • 对象的唯一性
  • 继承性
  • 抽象性——进行分类就是把一致性的数据(属性)和行为(操作)的对象抽象成类
  • 多态性——相同的操作或者函数作用与不同的对象时,会获得不同的结构

消息与方法

  • 消息:对象之间进行通信的结构
  • 方法:类中操作的实现过程

对象的三个内置方法

  • 使用类名创建一个对象时,会自动执行以下操作:

    • 在内存中给对象分配存储空间
    • 调用init方法,给对象的属性设置初始值的方法
    • 调用del方法,一个对象在内存中销毁前,的自动调用的方法
    • str方法,返回对象的描述信息,print函数输出使用
  • 可在定义的过程中将对象初始化

  • 每当创建一个对象时,该函数会自动执行,并且self必须为第一个参数

__init(self)__

>>> class Ball:
	def __init__(self,name):  #name为形参
		self.name=name  #在类的内部添加属性
	def kick(self):
		print("I'm %s. Nice to meet you!"%self.name)

		
>>> a=Ball('Bad')
>>> a.kick()
I'm Bad. Nice to meet you!
>>> b=Ball()
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    b=Ball()
TypeError: __init__() missing 1 required positional argument: 'name'
>>> 

self

  • 类——房屋设计的图纸
  • 对象——由房屋设计图纸实例化后的对象(多个房子)
  • self——每个具体对象(房子)的门牌号
  • 哪个对象在调用属性和方法,self就是指的哪个对象
  • self是一个指向实例本身的引用,用于访问类中的属性和方法,对象会把自身作为第一个参数传递给self
  • self相当于C/C++中的this指针
  • 在定义的时候,把self写在第一个参数
>>> class Ball:
	def setName(self,name):
		self.name=name
	def kick(self):
		print("I'm %s. Nice to meet you!"%self.name)

>>> a=Ball()
>>> a.setName("Bad")
>>> b=Ball()
>>> b.setName("Jay")
>>> a.kick()
I'm Bad. Nice to meet you!
>>> b.kick()
I'm Jay. Nice to meet you!

练习

  1. 编写一个python程序,创建三个类Person、 Teacher、 Student,这三个类中,Person是Teacher和Student的父类。类中的方法可以自己任意指定,用这三个类演示Python类的继承关系。
>>> class Person:
	def __init__(self):
		print("I AM BAD BOY!")

		
>>> class Teacher(Person):  #继承Person类
	pass

>>> class Student(Person):  #继承Person类
	pass

>>> jack=Teacher()  #调用父类方法
I AM BAD BOY!
>>> jerry=Student()
I AM BAD BOY!
>>> 
  1. 定义一个学生类:
  • 有下面的类属性:
    • 姓名
    • 年龄
    • 成绩(语文,数学,英语)[每课成绩的类型为整数]
  • 类方法:
    • 获取学生的姓名:get_name() 返回类型
    • str2 获取学生的年龄:get_age() 返回类型int
    • 返回3门科目中最高的分数:get_course() 返回类型int
      定义好类以后,定义一个对象进行测试
>>> class Student:
	def __init__(self,name,age,scores):
		self.name=name
		self.age=age
		self.scores=scores
	def get_name(self):
		return self.name
	def get_age(self):
		return self.age
	def get_scores(self):
		return max(self.scores)  #获得最大值

>>> stu1=Student("Bad",21,[85,86,87])
>>> print("Name:%s"%(stu1.get_name()))
Name:Bad
>>> print("Age:%s"%(stu1.get_age()))
Age:21
>>> print("The highest score in the three courses is %s"%(stu1.get_scores()))
The highest score in the three courses is 87

总结

  1. 对象=属性(静态,变量)+方法(动态,函数)
  2. 面向过程编程、面向对象编程
  3. Python无处不对象
  4. 封装、继承、多态

面向对象的三大特征

继承

  • 概述:
    • 继承是面向对象编程最重要的特性之一
    • 类能继承所有公有成员或者受保护成员
    • 基类、父类(被继承的类)
    • 子类、派生类(新的类)
    • 通过继承能够实现代码的重用
    • 可以通过类来理顺类与类之间的关系
>>> class Mylist(list):  #定义类
	pass

>>> list=Mylist()
>>> list.append(3)
>>> list.append(4)
>>> list.append(5)
>>> list
[3, 4, 5]
class ClassName(baseclasslist):
	"类的帮助信息"
	statement
  • ClassName用于指定类名
  • Baseclasslist基类、父类名,类之间用逗号隔开。不指定则使用Python对象的根类object
  • statement类的主体,由变量、方法和属性定义语句组成
>>> class Parent:  #定义父类
	def hello(self):
		print("I AM Bad!")

>>> class child(Parent):  #定义子类
	pass

>>> a=Parent()  #访问父类
>>> a.hello()
I AM Bad!
>>> b=child()  #调用父类方法
>>> b.hello()
I AM Bad!

方法重写

  • 覆盖,子类与父类同名方法
  • 拓展,在父类的方法基础上,实现子类特有的代码功能(super()
>>> class Fruit:
	color="red"
	def harvest(self,color):
		print("The fruit is "+color)
		print("The fruit is already harvested")
		print("The fruit is "+Fruit.color+"!")

>>> class Orange(Fruit):
	color="orange"
	def __init__(self):
		print("
I AM Orange")
	def harvest(self,color):
		print("The Orange is"+color)
		print("The Orange is already harvested")
		print("The Orange is"+Fruit.color+"!")
  • 父类的成员都会被子类继承
  • 当父类中的某个方法不完全适用于子类时,需要在子类中重写父类的方法

子类调用父类__init__()方法

>>> class Fruit:
	def __init__(self,color="green"):
		Fruit.color=color
	def harvest(self):
		print("The fruit is "+Fruit.color+"!")

>>> class Apple(Fruit):
	def __init__(self):
		print("I AM Apple!")

>>> apple=Apple()
I AM Apple!
>>> apple.harvest()
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    apple.harvest()
  File "<pyshell#87>", line 5, in harvest
    print("The fruit is "+Fruit.color+"!")
AttributeError: type object 'Fruit' has no attribute 'color'
>>>
  • 子类中定义__init__(),就不会自动调用父类的__init__()方法
  • 在子类中使用父类的__init__()方法,必须进行初始化
  • 需要在子类中使用super就()调用父类的__init__()方法
>>> class Fruit:
	def __init__(self,color="green"):
		Fruit.color=color
	def harvest(self):
		print("The fruit is "+Fruit.color+"!")

>>> class Apple(Fruit):
	def __init__(self):
		print("I AM Apple!")
		super().__init__()  #使用super()调用父类__init__()方法

>>> apple=Apple()
I AM Apple!
>>> apple.harvest()

多继承

  • 在多继承中,要避免出现方法相同时的多继承关系
  • __mro__方法搜索顺序
  • 查看mroprint(类名.__mro__)
>>> class A:
	def sample(self):
		print("I AM BAD!")
	def demo(self):
		print("Hello World!")

>>> class B:
	def sample(self):
		print("I AM BAD BOY!")
	def demo(self):
		print("You Are Han Han!")

>>> class C(A,B):
	pass

>>> c=C()
>>> c.sample()
I AM BAD!
>>> c.demo()
Hello World!
# 查看方法的查找顺序
>>> print(C.__mro__)  #方法搜索顺序,查看mro
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
>>> 

多态

>>> class A:
	def fun(self):
		print("I AM BAD!")

>>> class B:
	def fun(self):
		print("I AM BOY!")

>>> a=A()
>>> b=B()
>>> a.fun()
I AM BAD!
>>> b.fun()
I AM BOY!

封装

  • 面向对象技术的三大特征之一
  • 类内部的定义属性和方法,在类的外部可直接调用属性和方法来操作数据,从而隐藏类内部的复杂逻辑
  • Python没有特定的封装关键字,而是通过特定的名称实现对属性和方法的封装
  • 在Python中,为了保证类内部的某些属性、方法不被外部所访问,可在属性、方法名中添加:
    • __name__(前后双下划线)定义特殊方法,一般是Python定义的名字
    • _name(单下划线)表示protected(保护)类型,只允许类本身与子类进行访问
    • __name(双下划线)private(私有)类型,只允许定义该方法的类本身进行访问
      • 不能通过类的对象进行访问
      • 可通过“对象名.类名__name”访问
      • 可通过“类名.__name”访问
>>> class Person:  #定义Person类
	name="Bad"

>>> p=Person()  #定义对象
>>> p.name
'Bad'
>>> class Person():  #定义私有类
	__name="Bad"

>>> p=Person()  #定义对象
>>> p.__name  #访问
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    p.__name
AttributeError: 'Person' object has no attribute '__name'
>>> p.name  #访问
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    p.name
AttributeError: 'Person' object has no attribute 'name'
>>> 
>>> class Person:  #定义私有类
	__name="Bad"
	def getname(self):
		return self.__name

>>> p=Person()
>>> p.getname()
'Bad'
>>> p._Person__name
'Bad'

 

以上内容均属原创,如有不详或错误,敬请指出。
本文作者: 坏坏