python视频笔记20(面向对象详解)

【面向对象】:

软件编程的实质:

软件编程就是我们的思维转变成计算机能够识别的语言的一种过程

面向过程:

	1:自上而下按顺序执行
	2:其结构是按照功能划分若干个基本模块
	3:各模块关系尽可能简单
	4:每一个模块都是由顺序、选择、和循环三种基本结构
	5:其模块化实现的具体方法是子程序
	6:程序流程在写的时候就已经决定

面向对象:

	1:把数据和对数据的操作方式放在一起,作为一个相互依赖的整体
	2:对同类对象抽象出其共性,形成类
	3:类中的大多数据,只能用本类的方法进行处理
	4:类通过一个简单的外部接口和外界发生关系对象与对象之家通过消息进行通信息
	5:程序流程由用户在使用中决定

理解面向对象:

		1:面向对象是相对面向过程的
		2:面向对象和面向过程是一种思想

面向过程

			1:强调的是功能行为
			2:关注的是解决问题需要哪些步骤

面向对象:

			1:将功能封装进对象,强调具备勒功能的对象
			2:关注的是解决问题需要哪些对象
	面向对象是基于面向过程的
eg:把大象装进冰箱

面向过程:

		1:打开冰箱
		2:装进冰箱
		3:关闭冰箱

面向对象
更加符合人思考的习惯,从执行者变成了指挥者

		1:找到能把大象装进冰箱的人x
		2:让x去打开冰箱
		3:让x装大象
		4:让x关闭冰箱

面向对象特点:

	1:是一种复合人们思考习惯的思想
	2:可以将复杂的事情简单化
	3:将程序员从执行者变成指挥者
	完成需求时:
		先要去找具有所需功能的对象来用
		如果对象不存在,那么创建一个

类与对象的关系:

	1:使用计算机语言就是不断描述显示生活的事情
	2:python描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义
	3:对象即时该事务实实在在存在的个体

类的定义:

	1:生活中描述事务无非就是描述事务额名称/属性/行为
	2:python中用类来描述事务也是如此
		属性:对应类中的成员变量
		行为:对应类中的成员方法
	3:定义类其实在定义类中的成员(成员变量和成员方法)
	4:拥有相同(或者类似)属性和行为的对象都可以

类的设计:

	事务的名称
	属性
	行为
		eg1:
		类名:Wife
		属性:sex  age  height weight faceValue 
		行为:洗衣  做法  看电视  拖地

创建类:

类:数据类型,本身并不占内存空间,和number,string,boolean 等类
eg1:

		类名:Wife
		属性:sex  age  height weight faceValue 
		行为:洗衣  做法  看电视  拖地似用类

实例化对象(变量),对象占内存空间
创建类之前 需要设计类 如eg1 从三方面设计 类名首字母需要大学 其他遵循驼峰
格式:

		class Name (父类列表):
			属性
			行为

eg2:

		#object 基类、超类一般认为所有类的父类一般没有合适的父类就用object
		class Person(object):
		#定义属性
		name = ""
		age = 0
		height = 0
		weight = 0
		#定义方法(定义函数)
		#方法的参数必须以self当作第一个参数
		#self 代表类的实例(某个对象)
		def run(self,):
			print ("run")
		def eat(self,food):
			print ("eat" + food)
使用类实例化对象:

格式:
对象名 = 类名(参数列表)
注意:没有参数小括号也不能省略

	class Person(object):
		name = ""
		age = 0
		height = 0
		weight = 0
		def run(self,):
			print ("run")
		def eat(self,food):
			print ("eat" + food)
    #实例化对象
	per1 = Person()
	print (per1)
	per2 = Person()
	print (per2)

访问对象的属性与方法:

访问属性:

		格式:对象名.属性名
		赋值:对象名.属性名 = 新值
		per.name = "tom"
		per.age = 18
		···
		print (per.name, per.age)

访问方法:

		格式:对象名.方法名(参数列表)
		···
		per.run()
		per.eat("apple")

问题:目前来看person创建的对象都是一样的属性
对象的初始状态(构造函数):
init() 在使用类创建对象的时候自动调用
注意:如果不显示的写出构造函数,默认会自动添加一个空的

构造函数

	class Person(object):
		def run(self,):
			print ("run")
		def eat(self,food):
			print ("eat" + food)
		def __init__(self, name, age, height, weight):
			print (name, age, height, weight)
			self.name = name
			self.age = age
			self.height = height
			self.weight =weight
		per = Person("tom", 20, 170, 55)
		print (per.name, per.age)
		per = Person("jack", 22, 159, 55)
		print (per,name, per.age)

self:

代表类的实例,而非类
那个对象调用方法,那么该方法中的self就代码那个对象
self.class 代表类名

		class Person(object):
		def run(self,):
			print ("run")
			print (self.__class__)
		def eat(self,food):
			print ("eat" + food)
		def say(self):
			print ("Hello World name is %s ,%d years old" % (self.name, self.age)
		def __init__(self, name, age, height, weight):
			print (name, age, height, weight)
			self.name = name
			self.age = age
			self.height = height
			self.weight =weight
		per1 = Person("tom", 20, 190,90)
		per1.say()

析构函数:

和构造对立 del

class Person(object):
			def run(self,):
				print ("run")
				print (self.__class__)
			def eat(self,food):
				print ("eat" + food)
			def __init__(self, name, age, height, weight):
				print (name, age, height, weight)
				self.name = name
				self.age = age
				self.height = height
				self.weight =weight
			del __del__(self):
				print ("析构函数")
		per = Person("lucy", 20 , 189, 90)
		#释放对象 释放之后就不能访问勒
		del per
			def func():
				per2 = Person("a",1 ,1 ,1)
			func()
			while 1:
				pass
			
#在函数里定义的对象,会在函数结束时自动释放,这样可以用来减少内存空间的浪费		

重写__repr_与__str__函数:

重写:将函数重新定义写一遍
str() 在调用Print 打印时自动调用,是给用户用的 是一个描述对象的方法
repr() 给机器用的 ,在python解释器里面直接敲对象名 在回车后调用的方法
注意:在么有str时 且有repr,str=repr
优点:当一个对象的值很多,并且都需要打印,重写了__str_方法后简化了代码

	class Person(object):
		def __init__(self, name, age, height, weight):
			print (name, age, height, weight)
			self.name = name
			self.age = age
			self.height = height
			self.weight =weight
		def __repr__(self):
			return "%s-%d-%d-%d" % (self.name, self.age, self.height, self.weight)
	per = Person("lucy", 20 , 189, 90)
	per (per.name, per.age, per.height, per.weight)
	print (per)

访问控制:

	class Person(object):
		def run(self,):
			print ("run")
			print (self, __money)
			print (self.__class__)
		def eat(self,food):
			print ("eat" + food)
		def __init__(self, name, age, height, weight):
			print (name, age, height, weight)
			self.name = name
			self.age = age
			self.height = height
			self.weight =weight
			self.__money = money
			#通过内部的方法,修改私有属性]
		#通过自定义的方法实现对私有属性的赋值和取值
		def setMoney(self, money):
			#数据的过滤
			if money<0:
				money = 0 
			self.__money = money
		def getMoney(self):
			return.__money
	per = Person("lucy", 20 , 189, 90, 10000)
	per.age = 10 
	print (per.age)
	pre.run()

如果要让内部的属性不被外界直接访问如money在属性前面加两个下划线,在python中
如果在属性前加了两个下划线,那么这个属性就变成了私有属性
属性分为:公有 私有 受保护的
内部可以使用

pre.run()
	per.setMoney(10)
	print(per.setMoney())

不能直接访问per__money 的原因是因为Python解释器把
__money变成勒_Persion__money

但是可以使用_person__money 但建议不用这种,不同解释器可能存在解释的变量名不一样

	per._persion__money_ =1
	print(per.getMoney())

在Python中__xx__属于特殊变量,可以直接访问
在python 中_XXX 变量,外部也可以访问 意思是虽然我可以直接访问但是请视我为私有变量
#不要直接访问

	print (per.__age__)
	print (per._height)

例子:

开枪射击子弹:

分析

人:
类名:Person
属性:gun
行为:fire
枪:
类名:gun
属性:bulletBox
行为:shoot
弹夹:
类名:bulletBox
属性:bulletCount
行为:

		bulletBox.py
			class BulletBox(object):
				def __init__(self, count):
					self.bulletCount = Count
		gun.py
			class Gun(object):
				def __init__(self, bulletBox):
					self.bulletBox = bulletBox
				def shoot(self):
					if self.bulletBox.bulletCount==0:
						print("无子弹")
					else:
						self.bulletBox.bulletCount -= 1
						print ("剩余子弹:%d 发" % (self.bulletBox.bulletCount ))
		Person.py
			class Person(object):
				def __init__(self, gun):
					self.gun = gun
				def fire(self):
					self.gun.shoot()
				def fillBullet(self, count):
					self.gun.bulletBox.bulletCount = count

		from Person import Person
		from  gun import Gun
		from bulletBox import bulletBox
		bulletBox = BulletBox(5)
		gun = Gun(bulletBox)
		Per = Person(gun)
		per.fire()

继承:

有两个类,A类和B类,当我们说A类继承自B类A类就拥有勒B类中的属性和方法
object:是所有类的父类,还可以称为基类或超类
注意:继承者称为子类 被继承者称为父类

优点:

		1:简化勒代码 减少冗余
		2:提高勒代码的健壮性
		3:提高勒代码的安全性
		4:是多态的前提

缺点:

		耦合和内聚是描述类和类之间的关系的,耦合性越低,内聚性越高代码越好

如图:
python视频笔记20(面向对象详解)_第1张图片
单继承的实现:

person.py

	class Person(object):
			    def __init__(self, name, age):
			        self.name = name
			        self.age = age
			    def run(self):
			        print("run ")
			    def eat(self):
			        print( "eat" + food)

student.py

			from person import  Person
			class Student(Person):
			    def __init__(self, name, age):
			        #调用父类中的__init__
			        super(Student, self).__init__(name,age)

worker.py

			from person import  Person
			class Worker(Person):
			    def __init__(self, name, age):
			        #调用父类中的__init__
			        super(Worker, self).__init__(name,age)
		from student import  Student
		from worker import  Worker
		stu = Student("tom" ,12)
		print(stu.name, stu.age)
		stu.run()
		wor = Worker("lucy", 20)
		print(wor.name, wor.age)
		wor.eat("apple")

多继承:

注意:父类中方法名相同,默认调用的是在括号中排前面的父类方法
father.py

		class Father(object):
			def __init__(self, money):
				self.money  = money
			def run(self):
				print ("father  running ")

mother.py

		class Mother(object):
			def __init__(self, faceValue):
				self.faceValue  = faceValue
			def run(eat):
				print ("mouther eatting  ")					

clild.py

		from father import Father
		from mother import Mother
		class Child(father,mother):
			def __init__(self, money, faceValue):
				father.__init__(self, money)
				mother.__init__(self, faceValue)

多继承实现.py

		from clild import Clild

		def main():
			c = Child(300, 100)
			print (c.money, c.faceValue)
			c.run()
			c.eat()
			if __name__ = "__main__"
				main()							

多态:

一种事物的多种形态

例子:

最终目标:人可以喂任何一种动物
cat.py

	   				class Cat (object):
					def __init__(self, name):
				       	self.name = name
					def eat(self):
				       	print(self.name + " eat" )

mouse.py

					class Mouse (object):
					def __init__(self, name):
					       self.name = name
					def eat(self):
					       print(self.name + " eat" )

多态.py

					from cat import  Cat
					from mouse import  Mouse
					tom = Cat("tom")
					jerry = Mouse("jerry")
					tom.eat()
					jerry.eat()

再添加100 种动物,也有name属性和eat方法
定义一个有name属性和eat方法的animal类让所有动物类继承它

animal.py

					class Animal(object):
					def __init__(self, name):
					       self.name = name
					def eat(self):
					       print(self.name + " eat")

cat.py

					from animal import  Animal
					class Cat (Animal):
					    	def __init__(self, name):
					        	super(Cat, self).__init__(name)

mouse.py

					from animal import  Animal
					class Mouse (Animal):
					    	def __init__(self, name):
					        	super(Mouse, self).__init__(name)

定义一个人类 可以喂猫和老鼠吃东西

person.py

					class Person(object):
					def feedCat(self, cat):
					       print("给猫食物")
					       cat.eat()
					def feedMouse(self, mouse):
					       print ("给狗事物")
					       mouse.eat()
				per = Person()
				per.feedCat(tom)
				per.feedMouse(jerry)

人如果要喂养100种动物是否需要写100个feed

person.py

					class Person(object):
					def feedAnimal(self, animal):
					       print("食物")
					       animal.eat()
				per = Person()
				per.feedAnimal(tom)

对象属性与类属性:

	class Person(object):
		#此属性不叫做对象属性,实际上属于类属性(用类名来调用)
		name = "person"
		#此处为对象属性
		def __init__(self, name):
			self.name = name
	print (Person.name)
	per = Person("tom")
	print (per.name)

对象属性的优先级高于类属性
动态的给对象添加对象属性 只针对于当前对象生效 对于 类创建的其他对象没有作用

	per.age = 18
	print (Person.name)

动态给实例添加属性方法:
添加属性:

			#创建空类
			class Person(object):
				pass
			per = Person()
			#动态添加属性  体现了动态语言的特点(灵活)
			per.name = "tom"
			print (per.name)	

添加方法:

			from types import MethodType
			def sya(self):
				print ("my name is " + self.name)
			per.speak = MethodType(say, per)

如果想要限制实例的属性(比如只允许给对象添加name, age, height, weight)
在定义类的时候,定义一个特殊的属性(_slots),可以限制动态添加的属性

		_slots_ = ("name", "age", "age")

@property:

可以让你对受限制的属性使用.语法

	class Person(object):
		def __init__(self, age):
			self.__age = age
		def getAge(self):
			return self.__age
		def setAge(self):
			if age < 0:
				age = 0 
			else:
			self.__age = age
	person = Person(19)
	print (per.age)
#不安全直接对外暴露
#没有数据的过滤 
#使用限制访问,需要自己写set 和get 方法 才能访问
	per.setAge(18)
	print(per.getAge())

方法名为受限制的变量去掉双下划线

	class Person(object):
		def __init__(self, age):
			self.__age = age
		@property
		def age(self):
			return self.__age
		@age.setter
		def age(self, age):
			if age < 0 :
				age=0
			self._age =age
	per.age = 100# 相当于调用setAge
	print(per.age)#相当于调用getAge
	per.height = 190 #报错

你可能感兴趣的:(python)