理解:面向对象和面向过程是不同的解决代码的方式,面向对象是面向过程的升级(见知乎面向对象)。
- 面向过程:根据业务逻辑从上到下写代码。
- 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少重复代码的重写过程。
- 面向对象OO:按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法。
- 面向对象编程OOP:是一种解决软件复用的设计和编程方法,这种方法吧软件系统中相近相似的操作逻辑和操作应用数据,以类的形式描述出来。以对象实例的形态在软件系统中复用,以达到提高软件开发效率的作用。
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 类对象:
- 实例对象:
类和对象:(就像飞机图纸和真飞机的关系)
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征的行为的一组对象抽象定义,提出了另外一个新的概念--类 类就相当于制作飞机的图纸,用它来进行创建的飞机就相当于对象。
类简介: 人以类聚,物以群分
具有相似内部状态和运动规律的实体的集合(或统称为抽象)
具有相同属性和行为事物的统称。
类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的村子啊,一个类可以找到多个对象。
类的构成:
类由3个部分构成:
类的名称:类名 (命名规则按照大驼峰)
类的属性:一组数据
类的方法:允许对数据进行操作的方法(行为)
定义类: class 类名:
方法列表
class Car:
#初始化对象,第一步会初始化。
def __init__(self,new_name,new_car):
self.name = new_name
self.age = new_car
#方法
def getCarInfo(self):
print('车子的名字是:',self.name)
def move(self):
print('车子正在移动')
#创建一个对象
tc = Car('奔驰',1)#开辟内存,返回对象的引用
#添加属性
#tc.name = '大众'
tc.getCarInfo()
benz = Car()
benz.name = '奔驰'
benz.getCarInfo()
self指向自己,self代表着实例的引用。
而self.__class__则指向类。
self不一定要写成self,不过要尊重习惯,最好写self。
对象之间互相访问数据时,不要直接访问属性,要用一个方法返回给,防止篡改数据。
class Cat:
def __init__(self,name,age):
print(self)
print(self.__class__)
self.name = name
self.age = age
def eat(self):
print("开始吃东西!",self.name)
def drink(self):
print("开始喝东西")
c = Cat("Tom",5)
print(c)
c.eat()
运行结果:
<__main__.Cat object at 0x000001C7641CE550>
<class '__main__.Cat'>
<__main__.Cat object at 0x000001C7641CE550>
开始吃东西! Tom
- __init__ 方法: 初始化对象
- 创建对象时,会自动调用__init__方法,然后返回创建的对象引用。
- __str__方法:返回对象信息,需要带return
- 自动调用,不需要自己调,返回对象的描述信息(自己写的)
- 如果没有这个方法,当用print(对象)时,打印的是对象的引用地址。
class Car:
#初始化对象,第一步会初始化。
def __init__(self,new_name,new_car):
self.name = new_name
self.age = new_car
def __str__(self):
return "%s车子的车龄是%d"%(self.name,self.age)
#方法
def getCarInfo(self):
print('车子的名字是:',self.name)
benz = Car('奔驰',1)
print(benz)
__new__方法:构造方法包括创建对象和初始化对象,在python当中,分为两步执行:先执行__new__方法,然后执行__init__方法;
-
__new__
至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供 -
__new__
必须要有返回值,返回实例化出来的实例,这点在自己实现__new__
时要特别注意,可以return父类__new__
出来的实例,或者直接是object的__new__
出来的实例 -
__init__
有一个参数self,就是这个__new__
返回的实例,__init__
在__new__
的基础上可以完成一些其它初始化的动作,__init__
不需要返回值 -
我们可以将类比作制造商,
__new__
方法就是前期的原材料购买环节,__init__
方法就是在有原材料的基础上,加工,初始化商品环节
#__new__单例对象
class Dog(object):
__instance = None
def __init__(self,name):
print()
self.name = name
def __new__(cls,name): #必须要有cls,代表本类。
if cls.__instance == None:
cls.__instance = object.__new__(cls)
#必须要调用object中的__new__方法,否则无法创建对象
return cls.__instance
else:
return cls.__instance
d1 = Dog("d")
print(d1.name)
d2 = Dog("b")
print(d2.name)
print(id(d1),id(d2))
隐藏属性:(保护对象的属性)
如果有一个对象,当需要对其进行修改属性时,有2种方法:
对象名.属性名 = 数据 (直接修改)
对象名.方法名() (间接修改)
为了更好的保存属性安全,既不能随意修改。
1、将属性定义为私有属性
2、添加一个可以调用的方法,共调用
class Dog:
def set_age(self,new_age):
if 100 >new_age > 0 :
self.age = new_age
else:
self.age = 0
def get_age(self):
return self.age
def set_name(self,new_name):
self.name = new_name
def get_name(self):
return self.name
dog = Dog()
dog.set_age(10)
dog.set_name('小白')
print(dog.get_age())
print(dog.get_name())
私有方法:(通过下划线,私有化)
class Dog:
#通过加下划线,私有方法
def __test1(self):
print('调用成功')
#公有方法,可直接调用。
def test2(self):
if new_money > 10000:
self.__test1()
else:
print('调用失败')
print()
dog = Dog()
dog.test2(10000)
__del__ 方法:(当对象被删除会执行)
class Dog:
def __del__(self):
print('对象被删除')
def hello(self):
print()
dog1 = Dog()
dog2 = dog1
del dog2
继承:
在程序中,继承描述的时事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物。
父类,基类 ----- 子类 派生类
class Animal:
def eat(self):
print('---吃---')
def drink(self):
print('---喝---')
def sleep(self):
print('---睡---')
def run(self):
print('---跑---')
class Dog(Animal):
def bark(self):
print('---汪汪叫---')
a = Animal()
a.eat()
dog1 = Dog()
dog1.eat()
子类继承父类、父类的父类(继承可以多层继承)
class Animal:
def eat(self):
print('---吃---')
def drink(self):
print('---喝---')
def sleep(self):
print('---睡---')
def run(self):
print('---跑---')
class Dog(Animal):
def bark(self):
print('---汪汪叫---')
#哮天犬继承
class Xiaotq(Dog):
def fly(self):
print('---飞---')
xt = Xiaotq()
xt.eat()
重写(继承父类的方法不是你想要的,可以在子类里面定义一个一样的方法)。
调用被重写父类的方法:1、super().方法() 2、父类().方法(self)
class Dog(Animal):
def eat(self):
print('---吃---')
def drink(self):
print('---喝---')
def sleep(self):
print('---睡---')
def run(self):
print('---跑---')
def bark(self):
print('---汪汪叫---')
#哮天犬继承
class Xiaotq(Dog):
def fly(self):
print('---飞---')
#重写
def bark(self):
print('---狂叫---')
#第一种,调用被重写父类的方法
#Dog.bark(self) #调用父类的的叫
#第二种
super().bark()
xt = Xiaotq()
xt.eat()
私有方法、私有属性在继承中的表现()私有方法、属性不能被继承。
注:1、如果调用的方法里面有私有属性,可以调用。
2、如果在子类中实现了一个公有方法,这个方法不能调用父类的私有方法和属性 。
class A:
def __init__(self):
self.num1 = 100
self.__num2 = 200
#共有方法
def test1(self):
print('hell,world!')
#私有方法
def __test2(self):
print('-test2-')
#B继承A
class B(A):
def test4(self):
print('-test4-')
#私有的方法不能继承
b = B()
多继承(一个类有多个父类,并且具有他们的特征。)
注意:1、多继承父类中的方法一样,按照继承的顺序来调用。(类名.__mro__打印继承的顺序,搜索顺序。)
2、多继承的时候,尽量不要出现相同的方法名。
#多继承
class A:
def test1(self):
print('--test1')
class B:
def test2(self):
print('---test2')
#c继承多个父类A和B
class C(A,B):
pass
c = C()
c.test1()
c.test2()
多态(一类事物的多种形态)
多态性是指在不考虑实例类型的情况下使用实例,
让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数
#多态
class Dog(object):
def print_self(self):
print('大家好,我是xxx,希望以后大家多多关照。')
class Xiaotq(Dog):
def print_self(self):
print('hello everone,我是你们的老大')
def introduce(temp):
temp.print_self()
dog1 = Dog()
dog2 = Xiaotq()
introduce(dog2)
- 类属性,实例属性
- 类属性:类属性所属与类对象,并且多个实例对象之间共享同一个类属性。
- 实例属性:和具体的某个实例对象有关系,并且一个实例对象和另一个实例对象时不共享属性的
- 一个特殊的属性,能够知道这个对象的类。
class Tool(object):
#类属性
num = 0
#方法
def __init__(self,new_name):
#实例属性
self.name = new_name
Tool.num += 1
tool1 = Tool("铁锹")
tool2 = Tool("工兵铲")
tool3 = Tool("水桶")
print(Tool.num)
实例方法、类方法、静态方法
静态方法:如果想要做一个东西,和实例和类都有关系使用静态方法。
class Game(object):
#类属性
num = 0
#实例方法
def __init__(self):
#实例属性
self.name = "laowang"
#类方法
@classmethod
def add_num(cls):
#cls指向类,
cls.num = 100
#静态方法,可以用类去调用及静态方法
@staticmethod
def print_menu():
print("-------")
print("穿越火线")
print("1、开始游戏")
print("2、结束游戏")
print("--------")
game = Game()
Game.add_num()#可以通过类的名字调用类方法
#game.add_num()#还可以通过这个类创建出来的方法,去调用这个类方法。
print(Game.num)
Game.print_menu()
#game.print_menu()#通过实例对象调用静态方法
property:函数的作用是在新式类中返回属性值。
class Dog():
def __init__(self):
self.__name = None
def setName(self,value):
self.__name = value
def getName(self):
return self.__name
name = property(getName,setName) #险些getName,setName
d1 = Dog()
d1.name = 10
print(d1.name)
Python内置的@property
装饰器就是负责把一个方法变成属性调用的:
class Student(object):
@property #获取值的时候调用这个
def score(self):
return self._score
@score.setter #设置值的时候调用这个
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
s = Student()
s.score = 60 # OK,实际转化为s.set_score(60)
s.score # OK,实际转化为s.get_score()
运行结果:60