面向对象编程

面向对象编程

OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,

一个对象包含了数据操作数据的函数

面向过程:把程序当做一组命令集合顺序执行。

为了简化流程,面向过程一般把函数切分为子函数。来降低系统复杂度。

面向对象:把程序当做一组对象集合。

每个对象都可以互相接收发送处理指令消息,

程序的执行也就是一系列消息在对象之间传递、

python中万物皆对象。可以自定义对象,自定义对象数据类型对应了类的概念。

实例:

处理学生成绩,面向过程程序可以用如下方式:

#定义两个学生字典

>>> std1={'name':'Amy','score':98}

>>> std2={'name':'Ellen','score':89}

#打印信息函数

>>> def print_score(std):

... print('%s:%s'%(std['name'],std['score']))

...

>>> print_score(std1)

Amy:98

>>> print_score(std2)

Ellen:89

面向对象:首先思考的不是执行流程,而是学生这种类型可以定义一个对象

它包含了name,score两个属性,以及打印的方法。

>>> class Student(object):

... def __init__(self,name,score):

... self.name=name

... self.score=score

... def print_score(self):

... print('%s:%s'%(self.name,self.score))

...

>>> std1=Student('amy',98)

>>> std2=Student('ellen',89)

>>> std1.print_score()

amy:98

>>> std2.print_score()

ellen:89

类和实例

类是抽象的模板,实例是根据类创建出来的一个个具体对象。

每个对象都有自己的属性和方法。

定义类

class 类名(object):

语句。。

类名:通常大写开头单词

object:表示该类是从哪个类继承下来的。如果没有,默认用object即可。

创建实例

实例名=类名+()

>>> std1=Student('amy',98)

>>> std1

<__main__.Student object at 0x0000000002AE02E8>

>>> Student

绑定属性

std1.name= xxx

__init__方法:创建实例的时候,将属性强制写入进去

... def __init__(self,name,score):

... self.name=name

... self.score=score

注意:__init__方法的第一个参数永远是self,表示创建的实例本身。可以将属性绑定到self,self指向实例。

传参的时候不用将self传入,默认会将实例变量传入。

和普通的函数相比,唯一的区别就是,第一个参数永远是self,调用时也不用传参数。

面向对象的三大特征:封装,继承,多态

数据封装

在类内部定义访问数据的函数。外部程序无需关心如何实现,直接调用即可。

这些函数也可以称为数据的方法。

方法和函数关系:定义在类中的函数称为方法,外边的叫做函数。

>>> std3=Student('P',100)

>>> std3.print_score()

P:100

代码:

class Student(object):

def __init__(self, name, score):

self.name = name

self.score = score

def get_grade(self):

if self.score >= 90:

return 'A'

elif self.score >= 60:

return 'B'

else:

return 'C'

lisa = Student('Lisa', 99) bart = Student('Bart', 59) print(lisa.name, lisa.get_grade()) print(bart.name, bart.get_grade())

私有变量

如果想要内部属性不被外部访问,可以把属性的名称前加上两个下划线。

变为私有变量,只有内部可以访问,外部不能访问。

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

def print_score(self):

print('%s: %s' % (self.name, self.__score))

std1=Student('Amy',98)

std2=Student('Ellen',89)

print(std2.name)

print(std2.__score)

#std1.print_score()

#std2.print_score()

执行结果

Ellen

Traceback (most recent call last):

File "C:\Users\pangli-os\Desktop\practice.py", line 15, in

print(std2.score)

AttributeError: 'Student' object has no attribute 'score'

作用:确保了外部代码不能随意修改对象内部的状态

问题来了,如果外部想要读取和修改怎么办呢?

增加一个方法get_score(),用来获取成绩字段

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

def print_score(self):

print('%s: %s' % (self.name, self.__score))

def get_score(self):

return self.__score

std1=Student('Amy',98)

std2=Student('Ellen',89)

print(std2.name)

print(std2.get_score())

修改

增加一个方法set_score,用来设置分数

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

def print_score(self):

print('%s: %s' % (self.name, self.__score))

def get_score(self):

return self.__score

def set_score(self,score_new):

self.__score=score_new

#std1=Student('Amy',98)

std2=Student('Ellen',89)

print(std2.name)

print(std2.get_score())

std2.set_score(100)

练习:将上述代码,进行传参校验。只有传入的score值在0~100之间,才允许设置,否者报错

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

def print_score(self):

print('%s: %s' % (self.name, self.__score))

def get_score(self):

return self.__score

def set_score(self,score_new):

if 0<=score_new<=100:

self.__score=score_new

else:

raise ValueError('参数错误')

#std1=Student('Amy',98)

std2=Student('Ellen',89)

print(std2.name)

print(std2.get_score())

std2.set_score(100)

print(std2.get_score())

std2.set_score(123)

#std1.print_score()

#std2.print_score()

继承和多态

定义一个类如果从现有的class继承,新的class叫做子类

被继承的class称为基类,或者父类

class Animal(object):

def fun(self):

print('Animal is running....')

class Dog(Animal):

pass

class Cat(Animal):

pass

对于dog和cat来说,animal就是它的父类

继承的好处?

子类获得了父类的全部功能。Animal有run的功能,cat和dog也有run的 功能,不用重复定义。

class Animal(object):

def run(self):

print('Animal is running....')

class Dog(Animal):

pass

class Cat(Animal):

pass

dog=Dog()

dog.run()

也可以对子类增加一些方法

class Animal(object):

def run(self):

print('Animal is running....')

class Dog(Animal):

def run(self):

#子类中重写的方法,会覆盖父类的方法。

print('Dog is running....')

def eat(self):

print('Dog is eating....')

class Cat(Animal):

pass

dog=Dog()

dog.run()

dog.eat()

引申到另外一个概念,多态

定义类的时候,实际上就定义了一种数据类型

这种数据类型跟自带的没有区别,str,list,tuple

print(isinstance(dog,Dog))

print(isinstance(dog,Animal))

print(isinstance(dog,Cat))

总结:

1、 继承关系中,如果一个实例的数据类型是某个子类,

那么它的数据类型也可以当做一个父类。反之不行。

a=Animal()

dog=Dog()

dog.run()

dog.eat()

print(isinstance(dog,Dog))

print(isinstance(dog,Animal))

print(isinstance(a,Cat))

实例属性和类属性

实例属性:

class Student(object):

def __init__(self,name):

self.name=name

s=Student('Amy')

print(s.name)

类属性:

class Student(object):

age=20

def __init__(self,name):

self.name=name

class Student(object):

age=20

def __init__(self,name):

self.name=name

s=Student('Amy')

print(s.name) #打印实例属性

print(Student.name) #错误写法

print(s.age) #打印实例属性

print(Student.age) #打印类属性

实例属性优先级要高于类属性,重写会打印重写的值

class Student(object):

name='root'

s=Student()

s.name='Amy'

print(s.name)

你可能感兴趣的:(面向对象编程)