初识面向对象三(经典类/多态/鸭子类型/初识封装)

godisgirl godisgirl     2023-01-24     425

关键词:


py2中的经典类
coding:utf-8

class D:
pass
# def func(self):
# print(‘d‘)
class B(D):
pass
# def func(self):
# print(‘b‘)
class C(D):
pass
def func(self):
print(‘c‘)
class A(B,C):
pass
# def func(self):
# print(‘a‘)
a = A()
a.func()
python2.x中的经典类
多继承中深度优先
没有mro提示你顺序
没有super

python2中的新式类 基本和python3中的新式类相似
class D(object):
pass
def func(self):
# print(‘d‘)
class B(D):
pass
def func(self):
print(‘b‘)
class C(D):
pass
def func(self):
super(C,self).func()
print(‘c‘)
class A(B,C):
pass
# def func(self):
# print(‘a‘)
a = A()
a.func()
print(A.mro()) # 方法
print(A.__mro__) # 属性

python2.x版本中存在两种类
经典类
不主动继承object类的所有类都是经典类
继承关系遵循深度优先算法
没有mro,没有super
新式类
所有继承object类的都是新式类
和py3一样继承遵循mro顺序和c3算法
有mro方法,但是super的使用必须传参数super(子类名,对象名).方法名

python3.x中的类和py2.x中的新式类有什么区别???
不需要主动继承object
py3中super()可以直接用,py2中使用必须传参数super(子类名,对象名).方法名

所有继承了object类的都是新式类 <==> 所有的新式类都继承object类
PEP8规范 : 跨环境 无论在py2还是py3中定义一个新式类,都需要加上object这个继承
class 类名(object):
pass
class 子类(类名):
pass

python中处处是多态
python是一门自带多态的语言

java
强数据类型的语言
def pay(float money): # float 2.35 - 类 对象
print(money)
pay()

class Payment(object):pass
class Alipay(Payment):
def pay(self,money):
pass
class Wechatpay(Payment):
def pay(self,money):
pass
def pay(Payment person_obj,float money):
person_obj.pay(money)
alex = Alipay()
pay(alex,24.5)
yuan = Wechatpay()
print(yuan,23.5)
一个类表现出来的多种状态
支付Payment是一个类,多种状态: 使用阿里支付Alipay,使用微信支付Wechatpay
支付表现出来的多种状态 :
第一种状态 支付宝支付
第二种状态 微信支付
class Animal(object):pass
class Cat(Animal):
def eat(self):pass
class Dog(Animal):
def eat(self):pass
def eat(Animal obj):
obj.eat()
小花 = Cat() # 小花就是猫类的对象 类==类型==数据类型,小花的类型就是Cat
小黑 = Dog()
eat(小花)
eat(小黑)
int str list tuple dict set 内置的数据类型
Cat Dog Animal 自定义的类/数据类型
动物吃表现出来的多种状态:
猫吃
狗吃

python
class Cat(object):
def eat(self):pass
class Dog(object):
def eat(self):pass
def eat(obj):
obj.eat()
小花 = Cat() # 小花就是猫类的对象 类==类型==数据类型,小花的类型就是Cat
小黑 = Dog()
eat(小花)
eat(小黑)
动物吃表现出来的多种状态:
猫吃
狗吃

class Alipay(object):
def pay(self,money):
pass
class Wechatpay(object):
def pay(self,money):
pass
def pay(person_obj,money):
person_obj.pay(money)
alex = Alipay()
pay(alex,24.5)
yuan = Wechatpay()
print(yuan,23.5)
pay(‘abc‘,23.5)

总结
在python中体现的多态:
几个类拥有同名的方法,可以写一个函数,来统一进行调用 - 归一化设计
java要要求传递数据的数据类型? (通过继承来实现的)
是为了代码不出错,只要你能够顺利的调用这个函数,那么内部的执行就大大降低出错的概率
python却不要求?
更多的不是硬性的规定,但是可能会因为传递的参数不符合规则而使得代码报错,但是大大降低了代码繁琐程度


python特有的  鸭子类型是相对论
len()这个函数来说: str list dict set tuple 都是鸭子类型
鸭子 == 数据集合
对于len来说,它不关心给我的是一个具体的什么数据类型
只关心 能够计算长度的就是我接受的参数

在java中 用多态实现的
def len(object obj):
print(‘*‘*20)
return obj.__len__()

print(len(‘abcd‘))
print(len([1,2,3]))

在python中 用鸭子类型
不关心这个对象的数据类型,只要这个对象含有一个__len__就可以了
 对于len函数来说,含有__len__的所有的类都是鸭子类型
def len(obj):
print(‘*‘*20)
return obj.__len__()

print(len(‘abcd‘))
print(len([1,2,3]))


class Cat():
def eat(self):pass
def sleep(self):pass
def drink(self):pass
def play(self):pass
class Dog():
def eat(self):pass
def sleep(self):pass
def drink(self):pass
def play(self):pass
Cat和Dog就认为是鸭子类型
绝对的像 : 狗有的猫都有


class Cat():
def eat(self):pass
def sleep(self):pass
def drink(self):pass
def climb(self):pass
class Dog():
def eat(self):pass
def sleep(self):pass
def drink(self):pass
def ball(self):pass
eat
sleep

class Cat():
def eat(self):pass
def climb(self):pass
class Dog():
def eat(self):pass
def ball(self):pass
eat cat和dog还是鸭子类型


鸭子类型
是python语言中特有的,不依赖于继承和规范来进行的一种约定(依赖继承和规范特指:java中的多态和接口)
如果两个类都需要做某一件事情,那么应该起相同的名字,这个时候,对于做的这件事情来说,这两个类就变成了鸭子类(归一化设计的表现)


中心思想 : 不同类之间的相同的方法都应该用同一个名字

抽象类 规范 : 不同类之间的相同的方法都应该用同一个名字
接口类 规范: 不同类之间的相同的方法都应该用同一个名字
class Cat():
def eat(self):pass
class Dog():
def eat(self):pass
def eat(obj):
obj.eat()
归一化设计 :为了使用不同类中的方法,而要求 不同类之间的相同的方法都应该用同一个名字

class Animal:pass
class Cat(Animal):
def eat(self):pass
class Dog(Animal):
def eat(self):pass
def eat(Animal obj):
obj.eat()
多态 : 已经实现了"不同类之间的相同的方法都用同一个名字",解决不同类的对象的传参问题

class Cat:
def eat(self):pass
class Dog:
def eat(self):pass
def eat(obj):
obj.eat()
鸭子类型 : 不需要解决类的对象的传参问题,就可以直接利用已经实现的"不同类之间的相同的方法都用同一个名字"


初识封装
什么是封装?
广义上(大家认为的) :
把一类事务的相同的行为和属性归到一个类中
class Dog:
def bite(self):pass
狭义上(学术上的定论) :
把一些特殊的属性和方法藏在类中
外部无法调用,只有内部可以调用
class Dog:
def bite(self):pass
dog = Dog()
dog.bite() # 从一个类的外部调用了bite方法

class Dog:
dog_sum = 0
def __init__(self):
self.count() # 从一个类的内部调用了count方法
def count(self):
Dog.dog_sum += 1

alex = Dog()
print(Dog.dog_sum)

alex.count() # # 从一个类的外部调用了count方法
alex.count()
alex.count()
print(Dog.dog_sum)

隐藏静态属性
class Dog:
# dog_sum = 0 # 不安全,因为这个属性可以在类的外部被随便修改
__dog_sum = 0 # 安全,通过dog_sum方法和__变量名让属性变成只能看不能改的值
def __init__(self):
self.count()
def count(self):
Dog.__dog_sum += 1 # 可以从一个类的内部使用__dog_sum的属性
def dog_sum(self):
return Dog.__dog_sum

print(Dog.__dict__)
alex = Dog()
print(Dog.__dict__)
# print(Dog.__dog_sum) # 不可以从外部直接使用这个变量
print(alex.dog_sum())

class Dog:
__dog_sum = 0 # 私有的静态属性 _Dog__dog_sum
def __init__(self):
self.count()
def dog_sum(self):
return Dog.__dog_sum # 只要是在类的内部使用__名字,默认就被改成 _类名__名字

print(Dog.__dict__)
print(Dog._Dog__dog_sum) # 绝不能在后续我们的代码中出现这种情况
只要是在类的内部的名字前面加上双下划线
那么这个名字 就变成 私有的 (只能在类的内部使用,不能在类的外部使用)
在定义的时候,存储的名字就会发生变化 _类名__名字
因此 在类的外部就不会被调用到了
在类的内部 使用__名字,默认就被改成 _类名__名字

class Dog:
# dog_sum = 0 # 不安全,因为这个属性可以在类的外部被随便修改
__dog_sum = 0 # 安全,通过dog_sum方法和__变量名让属性变成只能看不能改的值
def __init__(self):
self.__count()
def __count(self):
Dog.__dog_sum += 1 # 可以从一个类的内部使用__dog_sum的属性
def dog_sum(self):
return Dog.__dog_sum

alex = Dog()
print(alex.dog_sum())
yuan = Dog()
print(yuan.dog_sum())

class Dog:
def __init__(self,name,password):
self.__name = name # 不希望某个值被随便修改
self.__password = password # 不希望某个值被从类的外部看到
def login(self,usr,pwd):
if usr == self.name and pwd == self.__password:
return True
def name(self):
return self.__name
def set_name(self,new_name):
if type(new_name) is str:
self.__name = new_name

alex = Dog(‘alex‘,‘sb123‘)
print(alex.login(‘alex‘,‘sb222‘))
print(alex.login(‘alex‘,‘sb123‘))

print(alex.name())
alex.set_name(‘alex_sb‘)
print(alex.name())

只能在类的内部被调用,保证了类内部数据的安全,不会被别人随意修改
私有静态属性 : 为了不随意被外部修改
私有方法 : 不希望被外部随意调用
私有的对象属性 :
不希望某个值被随便修改
不希望某个值被从类的外部看到



































































































































































































































































































































































面向对象之组合封装多态性鸭子类型(代码片段)

一、组合1.什么是组合一个对象的属性是来自于另外一个类的对象,称之为组合2.为何用组合组合也是用来解决类与类代码冗余的问题3.如何用组合#classFoo:#aaa=1111#def__init__(self,x,y):#self.x=x#self.y=y##deffunc1(self):#print(‘Foo内的功能‘)###c... 查看详情

面向对象三大特性(代码片段)

面向对象三大特性1.面向对象的三大特性:继承,封装,多态封装:将一堆代码或者数据等放到一个空间中,并且可以使用多态:同一个对象,多种形态.(python默认支持多态)封装:根据职责将属性和方法封装到一个抽象的类中继承:实现代码... 查看详情

初识面向对象-接口类抽象类封装

接口类#java:面向对象编程#设计模式——接口#接口类:python原生不支持#抽象类:python原生支持的fromabcimportabstractmethod,ABCMetaclassPayment(metaclass=ABCMeta):#元类默认的元类type@abstractmethoddefpay(self,money):pass#没有实现这个方法#规范... 查看详情

面向对象(代码片段)

面向对象三大特征封装多态继承类对象单继承super类的约束异常处理类的私有成员属性反射isinstance和issubclasstype双下方法面向对象(类)三大特征封装指函数,模块,类,对象等,将一些数据或者内容封装到一个空间,可以调用多态指一种... 查看详情

第一小节初识面向对象(代码片段)

阅读目录楔子面向过程vs面向对象初识面向对象  类的相关知识  对象的相关知识  对象之间的交互  类命名空间与对象、实例的命名空间  类的组合用法  初识面向对象小结面向对象的三大特性  继承  多态... 查看详情

初识八大基本数据类型的包装类——java面向对象基础(25)

一、总括*八大基本数据类型的包装类:将基本数据类型封装了类(引用类型)*基本数据类型包装类*byte--Byte*short--Short*int--Integer*long--Long*float--Float*double--Double*char--Character*boolean--Boolean二、Integer的一些简单的使用1.其包装类型与基... 查看详情

c++初识类和对象(代码片段)

类和对象(上)一.初步认识面向过程和面向对象二.类的引入三.类的定义四.类的访问限定符及封装1.访问限定符2.封装五.类的作用域六.类的实例化七.类对象模型1.计算类对象的大小2.类对象的存储方式八.this指针1.this指针... 查看详情

面向对象初识(代码片段)

目录面向对象初识面向过程与面向对象类和对象创建类创建对象类属性和实例属性系统类面向对象初识面向过程与面向对象编程语言发展历程:机器语言-->汇编语言-->高级语言数学向左,上帝向右。数学家的思维总是倾向于... 查看详情

多态,封装(代码片段)

####python面向对象的三大特征之一####python多态:python中处处都是多态python是一种弱类型的语言####java是强类型语言####比如:python中name="qq",java中int_i=666如果之间直接改变类型。python可以直接改变,java则会报错#######python的鸭子类型... 查看详情

c#之封装继承多态初识

封装就是把一些具体的功能实现写在一个文件内,留给外部一个接口,调用者通过接口调用方法,实现功能。 继承就是子类继承父类的所有属性和方法,然后在新增自己的属性跟该方法。 多态是父类有的方法,子类重载... 查看详情

面向对象初识(代码片段)

 一、概念在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法。使用面向对象而非全局变量和函数的原因有多个,但是面向对象的好处在于:1多态:可以对不同类型的对象执行... 查看详情

026面向对象05——封装(代码片段)

0、复习继承(了解)抽象类和接口类fromabcimportABCMeta,abstractmethodpython中没有内置接口的概念,所有的抽象类和接口类都是用来规范子类的接口类和抽象类不能被实例化多态(了解)java中的多态和python中的鸭子类型在某些强数据类型语言... 查看详情

python--面向对象之三个特性:封装继承多态(代码片段)

...区别示例:#!/usr/bin/envpython#-*-coding:utf-8-*-"""面向对象编程初识"""#先定义一个类classHello():#定义一个方法defsayHell(self,name):print(‘欢迎您!‘+name)#创建一个对象obj=Hello()obj.sayHell(‘yusheng_liang‘) 二、面向对象--封装应用场景:  ... 查看详情

初识面向对象

1.初识面向对象  面向过程:    一切以事务的发展流程为中心.  面向对象:    一切以对象为中心.一切皆为对象.具体的某一个事务就是对象  打比方:    大象进冰箱    步骤:第一步,开门,第二步,装大象... 查看详情

python基础之面向对象初识与类的封装

一: 面向对象类的初识#(1)类的定义#三种方式:#1.classMyClass:    pass#2.推荐classMyClass():    pass#3.classMyClass(object):    pass#(2)类的实例化classMyClass():&n 查看详情

面向对象三要素:封装,继承,多态

面向对象三要素是:封装继承多态封装 封装就是事物抽象为类,把对外接口暴露,将实现和内部数据隐藏。继承面向对象编程(OOP)语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,... 查看详情

第六章(代码片段)

 阅读目录面向过程vs面向对象初识面向对象  类的相关知识  对象的相关知识  对象之间的交互  类命名空间与对象、实例的命名空间  类的组合用法  初识面向对象小结面向对象的三大特性  继承  多态... 查看详情

面向对象初识

面向过程和面向对象的区别面向过程面向过程是强调怎么做?把完成某一个需求的所有步骤从头到尾逐步实现。根据开发需求,将某些功能独立代码封装成一个又一个的函数最后完成的代码,就是顺序的调用不同的函数特点:注... 查看详情