私有属性和方法(实现封装)
Python对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有属性和私有方法.有如下要点:
1.通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
2.类内部可以访问私有属性(方法)
3.类外部不能直接访问私有属性(方法)
4.类外部可以通过”类名_私有属性(方法)名" 访问私有属性(方法)
#测试私有属性、私有方法
class Student:
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def __work(self): #私有方法
print("hardwork")
print("age:{0}".format(self.__age))
e = Student("张三",18)
print(e.name)
#print(e.age)
print(e._Student__age)
e._Student__work()
@property装饰器
@property可以将一个方 法的调用方式变成“属性调用”。下 面是一一个简单的示例,
#测试@property的用法
class Employee:
@property
def salary(self):
print("salary")
return 10000
emp1 = Employee()
#emp1.salary()
print(emp1.salary)
面向对象三大特征说明
python 是面向对象的语言,也支持面向对象编程的三大特性
封装
隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”, 只对外暴露“相关调用方法”.通过前面的“私有属性、私有方法”的方式,实现“封装”。
继承
继承可以让子类具有父类的特性,提高了代码的重用性。从设计.上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进已有的算法。
多态
多态是指同一一个方法调用由于对象不同会产生不同的行为。
继承
语法格式
Python支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:
class子类类名(父类 1[,父类2,.. ]):
类体
如果在类定义中没有指定父类,则默认父类是object类。也就是说, object是所有类的父类,里面定义了- -些所有类共有的默认实现,比如: _ new_ ().
定义子类时,必须在其构造函数中调用父类的构造函数。调用格式如下:
父类名_ jinit__ (self, 参数列表)
#测试继承的基本使用
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def say_age(self):
print("年龄19")
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #必须显式调用父类的初始化方法,不然解释器不会去调用
self.score = score
#Student-->Person-->object类
print(Student.mro())
s = Student("jack",19,90)
s.say_age()
print(s.name)
#print(s.age)
print(dir(s))
print(s._Person__age) #调用父类私有属性
类成员的继承和重写
1.成员继承:子类继承了父类除构造方法之外的所有成员。
2.方法重写:子类可以重新定义父类中的方法q这样就会覆盖父类的方法,也称为“重写”
#测试方法的重写
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def say_age(self):
print("我的年龄:",self.__age)
def say_introduce(self):
print("我的名字时{0}".format(self.name))
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #必须显式调用父类的初始化方法,不然解释器不会去调用
self.score = score
def say_introduce(self):
'''重写父类方法'''
print("报告老师,我的名字是:{0}".format(self.name))
s =Student("jack",16,90)
s.say_age()
s.say_introduce()
dir()和mro()
内置函数dir() ,他可以让我们方便的看到指定对象所有的属性
通过类的方法mro(或者类的属性_ mro_ 可以输出这个类的继承层次结构。
重写__str__()方法
object有一-个_ _str_ ()方法 ,用于返回- -个对于“对象的描述”, 对应于内置函数str()经常用于print0方法,帮助我们查看对象的信息。- str_ ()可以重写.
#测试重写object的__str__()
class Person: #默认继承object类
def __init__(self,name,):
self.name = name
def __str__(self):
return "my name is :{0}".format(self.name)
p = Person("JCAK")
print(p)
多重继承
Python支持多重继承,一个子类可以有多个“直接父类"。这样,就具备了“多个父类”的特点。但是由于,这样会被"类的整体层次"搞的异常复杂,尽量避免使用。
super()获得父类的定义
在子类中,如果想要获得父类的方法时,我们可以通过super()来做。super()代表父类的定义,不是父类对象。
多态
多态( polymorphism )是指同一个方法调用由于对象不同可能会产生不同的行为。关于多态要注意以下2点:
1.多态是方法的多态,属性没有多态。
2.多态的存在有2个必要条件:继承、方法重写.
#多态
class Man:
def eat(self):
print("饿了吃饭")
class Chinese(Man):
def eat(self):
print("中国人用筷子吃饭")
class English(Man):
def eat(self):
print("英国人用叉子吃饭")
class Indian(Man):
def eat(self):
print("印度人用手吃饭")
def ManEat(m):
if isinstance(m,Man):
m.eat() #多态 一个方法调用,根据对象不同调用不同的方法
else:
print("不能吃饭")
ManEat(Chinese())
特殊方法和特殊属性和运算符重载
方法 | 说明 | 例子 |
__init__ | 构造方法 | 对象创建: p = Person() |
__del__ | 析构方法 | 对象回收 |
_-repr_ ,_ str_ | 打印,转换 | print(a) |
__call__ | 函数调用 | a() |
__getattr__ | 点号运算 | a.Xxx |
__setattr__ | 属性赋值 | a.xxx = value |
__getitem__ | 索引运算 | a[key] |
__setitem__ | 索弓|赋值 | a[key]=value |
__len__ | 长度 | len(a) |
运算符 | 特殊方法 | 说明 |
运算符+ | _add__ | 加法 |
运算符- | _sub_ | 减法 |
<,<=,== | __It_ ,_ le_,_ eq_ | 比较运算符 |
>,>=,!= | _gt_ ,_ _ge_ _ne_ | 比较运算符 |
|,^,& | __or__ ,_ xor_ _and_ | 或、异或、与 |
<<,> > | _lshift_ ,_ _rshift_ | 左移、右移 |
*,/,%,// | _mul_ ,_truediv_ __mod_ _floordiv_ | 乘、 浮点除、模运算(取余)、整数除 |
** | __pow__ | 指数运算 |
特殊属性 | 含义 |
obj__dict__ | 对象的属性字典 |
obj__class__ | 对象所属的类 |
class.__bases_ | 类的基类元组(多继承) |
class.__base_ | 类的基类 |
class.__mro__ | 类层次结构 |
class. __subclasses_ () | 子类列表 |
对象的浅拷贝、深拷贝
#测试对象的浅拷贝、深拷贝
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self):
print("开始计算")
print("cpu对象:",self)
class Screen:
def show(self):
print("显示一个好看的画面")
print("screen对象:",self)
#测试变量赋值
c1 = CPU()
c2 = c1
print(c1)
print(c2)
print("测试浅拷贝")
#测试浅拷贝
s1 = Screen()
m1 = MobilePhone(c1,s1)
m2 = copy.copy(m1)
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
#测试深拷贝
print("测试深拷贝")
m3 = copy.deepcopy(m1)
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
组合
#测试组合
class A1:
def say_a1(self):
print("a1")
class B1(A1):
def __init__(self):
pass
b1 = B1()
b1.say_a1()
class A2:
def say_a2(self):
print("a2")
class B2:
def __init__(self,a):
self.a = a
a2 = A2()
b2 = B2(a2)
b2.a.say_a2()