面向对象的特征: 封装,继承,多态
不使用继承写代码:代码量多,冗余
使用继承写代码: 灵活,看起来很舒服,节约代码量
表示继承: 子类的类名后面加上括号,括号内写入父类的类名
继承的特性:子类继承父类,那么子类就拥有父类的所以属性和方法
继承于同一个父类的子类,不能相互调用方法
继承的传递性:
父亲继承于爷爷,儿子继承于父亲,那么儿子就拥有父亲和爷爷的属性和方法
object(基类),原类 是所有类的父亲,相当于是祖宗
object的子类,统称为派生类
当我们自己定义的类中,写了init,str,bel方法的时候,
实际上相当于重写了obkect类中的方法
lass Animal:
def eat(self):
print('吃东西')
def run(self):
print('奔跑')
class Dog(Animal):
def bark(self):
print('汪汪汪的叫')
def pushers(self):
print('拆家')
class Cat(Animal):
def bark(self):
print('喵喵')
=====================
子类重写父类方法
子类调用父类的方法
1,super() 只会向上找,直接找父类 儿子只会找父亲,父亲只会找爷爷
2,父类名称.方法 可以跨级取找,但是不利于修改,如果父类改名之后,那么就找不到了
class GrandFather:
def darive(self):
print('开坦克')
class Father(GrandFather):
def darive(self):
print('开挖机')
super().darive()
class Son(Father):
def darive(self):
print('开赛车')
# 子类调用父类方法 super()
super().darive()
# 父类名称.方法
# GrandFather.darive(self)
===========================
对于父类的私有权限,子类不能直接获取
如果子类想要获取的私有权限,则可以定义公有方法进行访问
class Father:
def __init__(self):
self.name = '张三'
self.__money = 2000 # 私有属性
def __hide_money(self):
print('这是父亲的私有方法,有%s块'%self.__money)
def get_money(self):
print('这是父类的公有方法,访问私有权限:私有属性为%s'%self.__money)
self.__hide_money()
class Son(Father):
pass
xiaoming = Son()
print(xiaoming.name)
# 父类的私有属性,子类无法获取
# print(xiaoming.__money)
# 父类的私有方法,子类无法获取
# print(xiaoming.__hide_money)
xiaoming.get_money()
======================
多继承: 一个子类拥有多个父类
class Father:
def __init__(self):
self.eye = '双眼皮'
def eat(self):
print('喜欢吃青菜')
class Mother:
def __init__(self):
self.eye = '单眼皮'
def eat(self):
print('喜欢吃青菜')
class Son(Mother,Father):
pass
xiaoming = Son()
print(xiaoming.eye)
xiaoming.eat()
# __mro__ 查看调用顺序
print(Son.__mro__)
========================
多态:同一种事物的多种形态
class Dog:
def game(self):
print('普通的小狗,简单玩一玩')
class XiaoTianQuan(Dog):
def game(self):
print('够神,肯定不一样,飞天上玩')
class Person:
def play_with_dog(self,dog):
dog.game()
erha = Dog()
xiaotian = XiaoTianQuan()
# 创建人类对象
xiaoming = Person()
xiaoming.play_with_dog(erha)
=============================
类属性:定义在类中的属性
类属性实例和类都能访问,但是只能通过类修改
# class A:
# age = 18 # 类属性
# # self代表你是是一个实例(对象)方法
# def __init__(self,name):
# self.name = name
# a1 = A('huahua')
# print(a1.name)
# 类对象不能访问实例属性
# print(A.name)
# 实例对象能访问类属性
# print(a1.age)
# print(A.age)
# 实例对象修改实例属性
# a1.name = '小花'
# print(a1.name)
# 修改类属性 通过类对象去修改
# A.age = 20
# print(A.age)
# print(a1.name)
# 通过实例去修改,通过实例对象修改属性的时候,相当于给实例对象添加了属性
# 类属性只能通过类对象去修改
# a1.age = 30
# print(a1.age)
# print(A.age)
============================
装饰器: 具有特殊作用的函数,用来装饰函数的
类方法:使用装饰器@classmethod
实例对象和类对象都能去使用
静态方法: 使用装饰器 @staticmethod
class Tool:
count = 0 # 类属性,记录创建工具的总数
def __init__(self, name):
self.name = name
# 计算
Tool.count += 1
@classmethod # 类方法
def show_tool_count(cls):
print('工具总数%s'%cls.count)
# 创建工具对象
tools1 = Tool('斧头')
tools2 = Tool('榔头')
tools3 = Tool('铁锹')
tools1.show_tool_count()
Tool.show_tool_count()
# 静态方法
class Dog:
@staticmethod
def run():
print('狗在跑')
erha = Dog()
erha.run()
Dog.run()
====================
__new__: 创建对象的时候去调用
创建对象
lass Person:
def __init__(self):
print('我是init方法')
def __str__(self):
return '我是str方法'
def __del__(self):
print('我是del方法')
def __new__(cls, *args, **kwargs):
print('我是new方法')
return super().__new__(cls) # 让父类new方法帮我创建对象
# 并没有创建对象
a1 = Person()
print(a1)
======================
单例模式:一个类只能创建一个对象
class Person:
# 定义类属性 ,用来保存对象,开辟内存空间
__money = None
# 重构new方法
def __new__(cls, *args, **kwargs):
if cls.__money is None:
# 借助父类的new帮忙创建
cls.__money = object.__new__(cls)
return cls.__money
else:
return cls.__money
a = Person()
b = Person()
print(id(a))
print(id(b))
=========================