面向对象编程:
oop [object oriented programming]一种python的编程思路
面向过程:
就是我们一开始学习的,按照解决问题的步骤去写代码(根据业务逻辑去写代码)
在思考问题的时候, 首先分析“怎么按照步骤去实现”然后将问题解决拆解成若干个步骤,并将这些步骤对应成方法一步一步的,最终完成功能
面向对象:
关注的是设计思维
从计算机的角度来看:面向过程不适合做大项目
而面向对象合适做更大项目的设计
类和对象
类:类是具有一组 相同或者相似特征【属性】和行为【方法】的一系列[多个]对象组合
现实世界 计算机世界
行为---------->方法
特征---------->属性
对象: 对象是实实在在的一个东西,类的实例化,具象化
类是对象的抽象化 而对象是类的一个实例
实例方法:在类的内部,使用def 关键字来定义 第一个参数默认是 self(名字标识可以是其他的名字,但是这个位置必须被占用)
实例方法是归于 类的实例所有
属性:类属性 实例属性
在类的内部定义的变量(类属性)
在方法内部定义的(通过类似于self.变量名)变量,是实例属性
self
1、self只有在类中定义实例方法的时候才有意义,在调用时候不必传入相应的参数,而是由显示器自动去指向
2、self的名字是可以更改的,可以定义成其他的名字,只是约定俗成的定义成self
3、self指的是类实例对象本身,而不是类本身,相当于Java中的this
魔法方法
__init__方法:初始化一个类,在创建实例对象为其赋值时使用。
__str__方法:在将对象转换成字符串 str(对象) 测试的时候,打印对象的信息。
__new__方法:创建并返回一个实例对象,调用了一次,就会得到一个对象。
__class__方法:获得已知对象的类 ( 对象.__class__)。
__del__方法:对象在程序运行结束后进行对象销毁的时候调用这个方法,来释放资源。
init
python自带的内置函数,具有特殊的函数,使用双下划线包起来的(魔术方法)
是一个初始化的方法,用来定义实例属性,和初始化数据的,在创建对象的时候自动调用,不用手动去调用
利用传参的机制可以让我们定义功能更加强大并且方便的类
class People():
def eater(self):
print("xiaoqian is a hero")
pass
pass
class Person():
def __init__(self, age, name, sex):
'''
实例属性的声明
:param age:
:param name:
:param sex:
'''
self.name = name
self.age = age
self.sex = sex
pass
def eat(self, food):
print(self.name+'喜欢吃'+food)
pass
pass
xq = People()
xq.name = "xiaoqian" # 添加实例属性
print(xq.name)
xq.eater()
xm = Person(19, '小美', 'female')
print("{}的年龄是{}".format(xm.name, xm.age))
xm.eat('banana')
# 小美的年龄是19
# 小美喜欢吃banana
class Animals(object):
'''
介绍str的使用效果,使用外层的内容和使用#标注的魔法方法的效果是一样的
'''
def __init__(self, name, color):
self.name = name
self.color = color
pass
# def __str__(self):
# return "My name is %s, and I am %s"%(dog.name, dog.color)
pass
dog = Animals('WANGCAI', 'white')
print("My name is %s, and I am %s"%(dog.name, dog.color))
# print(dog)
父类继承和覆盖
class Dog:
def __init__(self, name, color):
self.name = name
self.color = color
pass
def bark(self):
print('wangwang')
pass
pass
class kejidog(Dog):
def __init__(self, name, color, height):
super().__init__(name, color)
# 或者写成:super(kejidog, self).__init__(name, color)
# 介绍super方法,这样继承也可以Dog.__init__(self, name, color)
self.height = height
self.weight = 2
pass
def bark(self):
print(self.name)
# 这里必须用到super
super().bark()
print('wwwwww')
pass
def __str__(self):
return 'the dog is {}, it is in {}, it\'s{}height, it is {} weight'.format(self.name, self.color, self.height, self.weight)
keji = kejidog('xiaogou', 'red', 4)
keji.bark()
print(keji)
# xiaogou
# wangwang
# wwwwww
# the dog is xiaogou, it is in red, it's4height, it is 2 weight
实例属性和类属性
属性:类属性和实例属性
类属性 就是类对象所拥有的属性
类属性是可以 被类对象和实例对象共同访问使用的
实例属性只能由实例对象所访问
class Student:
name='李明' #属于类属性 就是student类对象所拥有的
def __init__(self,age):
self.age=age #实例属性
pass
def aaa(x,y):
print(x+y)
pass
Student.name='李易峰' #通过类对象去修改数据 可以修改的 因为name的所拥有的权利属于类对象
lm=Student(18)
print(lm.name) #通过实例对象去访问类属性
# lm.name='刘德华' #通过实例对象 对类属性进行修改 可以吗? 不可以的
print(lm.name)
print(lm.age)
print('---------xh的数据---------------')
xh=Student(28)
print(xh.name)
print(xh.age)
# 李易峰
# 李易峰
# 18
# ---------xh的数据---------------
# 李易峰
# 28
print(Student.name) 如 类名.属性名 形式去访问
类方法和静态方法
类方法
class People:
country = 'China'
# 这里不用classmethod会导致People.get_country()找不到对应的值,只能通过建立一个p对象
# 类方法的第一个参数是类对象cls,通过cls引用的类对象的属性和方法
@classmethod
def get_country(cls):
return cls.country
pass
p = People()
print(p.country)
print(p.get_country())
print(People.get_country())
静态方法
为什么要使用静态方法呢
1、由于静态方法主要来存放逻辑性的代码,本身和类以及实例对象没有交互
2、也就是说,在静态方法中,不会涉及到类中方法和属性的操作
3、数据资源能够得到有效的充分利用
import time
class TimeTest:
# 实例方法的第一个参数是实例对象self,通过self引用的可能是类属性(不用init)、也有可能是实例属性(用init),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
def __init__(self, hour, min, sec):
self.hour = hour
self.min = min
self.sec = sec
pass
@staticmethod
def showtime():
return time.strftime('%H:%M:%S', time.localtime())
# 静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。
print(TimeTest.showtime())
t = TimeTest(8, 40, 32)
print(t.showtime())
下划线说明
_xxx
前面加一个下划线,以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能使用from xxx import * 的方式导入。
__xx
前面两个下划线,声明该属性为私有,不能在类的外部被使用或直接访问。 可分为私有化属性和私有化方法两种。
__xxx__
前后两个下滑线,魔法方法,一般是python自有,开发者不要创建这类型的方法。
xxx_
后面单下滑线,避免属性名与python关键字冲突。
两种实现属性函数(property)的方法
class Person:
def __init__(self):
self.__age = 24
pass
def get_age(self):
return self.__age
def set_age(self, age):
if age < 0:
print('False!')
pass
else:
self.__age = age
pass
pass
# 定义一个类属性, 实现通过直接访问属性的形式去访问私有的属性
age = property(get_age, set_age)
pass
p1 = Person()
print(p1.age)
p1.age = 4
print(p1.age)
# print(p1.get_age())
# p1.set_age(2)
# print(p1.get_age())
class Person:
def __init__(self):
self.__age = 42
pass
# 通过装饰器的方式去声明
@property # 用装饰器修饰, 添加属性标志, 提供一个getter方法
def age(self):
return self.__age
@age.setter # 提供一个setter方法
def age(self, age):
if age < 0:
print('FALSE!')
pass
else:
self.__age = age
pass
pass
pass
p1 = Person()
print(p1.age)
p1.age = -4
print(p1.age)