一、类的封装:

1.概念:

广义的封装:函数和类的定义本身,就是封装的体现

狭义的封装:一个类的某些属性,在使用的过程 中,不希望被外界直接访问,而是把这个属性给作为私有的【只有当前类持有】,然后暴露给外界一个访问的方法即可【间接访问属性】

封装的本质:就是属性私有化的过程

封装的好处:提高了数据的安全性,提高了数据的复用性

2.属性、方法的私有化:

如果想让成员变量不被外界直接访问,则可以在属性名称的前面添加两个下划线__,成员变量则被称为私有成员变量

私有属性的特点:只能在类的内部直接被访问,在外界不能直接访问

# 类
class Person:def __init__(self, name, age, sex):self.name = name  # 公有属性self.__age = age  # 私有属性: 双下划线开头的属性, 只能在当前类内部使用self._sex = sex  # 公有属性,但是不建议这么写def run(self):print(self.__age)self.__eat()# 私有方法def __eat(self):print("eat")# 对象
p = Person('鹿晗', 30, '男')
print(p.name)
# print(p.__age)  # 报错,__age是私有属性
print(p._sex)
p.run()
print()# p.__eat()  # 报错,__eat()是私有方法

类中出现 ‘__属性名/__方法名’时说明属性/方法是私有属性/方法,子类无法继承且外部无法调用。

在上述程序中私有类__sex与私有方法__eat()都是无法调用的,但是可以通过其他手段进行调用,但是不介意这样使用。

下面的方式可以调用私有属性或私有方法,但是不要这么用
print(p._Person__age)
p._Person__eat()

3.get函数和set函数

get函数和set函数并不是系统的函数,而是自定义的,为了和封装的概念相吻合,起名为getXxx和setXxx

get函数:获取值

set函数:赋值【传值】

因为类的私有属性/方法是无法被继承与调用的,因此我们引入get函数与set函数来对私有属性/方法进行获取与修改。

class Person2():def __init__(self,name,age):self.name = nameself.__age = age#特殊情况一self.__weight__ = 20.0#特殊情况二self._height = 155.0def myPrint(self):print(self.name,self.__age)
p2 = Person2("abc",10)
p2.myPrint()   #abc 10

3.1 get函数:


#get函数:获取成员变量的值#命名方式:getXxx#特点:需要设置返回值,将成员变量的值返回def getAge(self):return self.__ageprint(p2.getAge()) #  10

3.2 set函数:

 #set函数:给成员变量赋值#命名方式:setXxx#特点:需要设置参数,参数和私有成员变量有关def setAge(self,age):#数据的过滤if age < 0:age = 0self.__age = age
p2.setAge(22)
print(p2.getAge()) # 22

总结:通过将属性私有化之后,然后提供get函数和set函数,外部代码就不能随意更改成员变量的值,这样在一定程度上保证了数据的安全性

4.@property装饰器

装饰器的作用:可以给函数动态添加功能,对于类的成员方法,装饰器一样起作用

Python内置的@property装饰器的作用:将一个函数变成属性使用

@property装饰器:简化get函数和set函数

使用:@property装饰器作用相当于get函数,同时,会生成一个新的装饰器@属性名.settter,相当于set函数的作用

作用:使用在类中的成员函数中,可以简化代码,同时可以保证对参数做校验

class Person1():def __init__(self,name,age):self.__name = nameself.__age = agedef myPrint(self):print(self.__name,self.__age)@propertydef age(self):return  self.__age#注意:函数的命名方式:需要和@property中函数的命名保持一致#作用:相当于set函数,设置参数,给成员变量赋值@age.setterdef age(self,age):if age < 0:age = 0self.__age = age@propertydef name(self):return  self.__name@name.setterdef name(self,name):self.__name = namep1 = Person1("abc",10)
p1.myPrint()   #abc 10
#p1.setAge(20)
#print(p1.getAge())print(p1.age)  #10
p1.age = 18   #相当于调用了set函数,将18传值,实质调用的是@age.setter修饰的函数
print(p1.age) #相当于调用了get函数,将成员变量的值获取出来,实质调用的是@peoperty修饰的函数p1.name = "zhangsan"
print(p1.name)

5.私有方法

如果类中的一个函数名前面添加__,则认为这个成员函数时私有化的

特点:也不能在外界直接调用,只能在类的内类调用

class Site():def __init__(self,name):self.name = namedef who(self):print(self.name)self.__foo()#私有成员方法,只能在当前类的内部内调用def __foo(self):    #私有函数print("foo")def foo(self):    #公开函数print("foo~~~~")#注意:以上两个函数是两个不同的函数,不存在覆盖的问题s = Site("shenshi")
s.who()
#s.__foo()  #AttributeError: 'Site' object has no attribute 'foo'
s.foo()

二、类的继承:

1.概念:

如果两个或者两个以上的类具有相同的属性或者成员方法,我们可以抽取一个类出来,在抽取的类中声明公共的部分

​ 被抽取出来的类:父类,基类,超类,根类

​ 两个或者两个以上的类:子类,派生类

​ 他们之间的关系:子类 继承自 父类

注意:

​ a.object是所有类的父类,如果一个类没有显式指明它的父类,则默认为object

​ b.简化代码,提高代码的复用性

2.单继承:

2.1 使用:

简单来说,一个子类只能有一个父类,被称为单继承

语法:

父类:

class 父类类名(object):

​ 类体【所有子类公共的部分】

子类:

class 子类类名(父类类名):

​ 类体【子类特有的属性和成员方法】

说明:一般情况下,如果一个类没有显式的指明父类,则统统书写为object

person.py文件【父类】

#1.定义父类
class Person(object):#构造函数【成员变量】def __init__(self,name,age):self.name = nameself.age = age#成员方法def show(self):print("show")def __fun(self):print("fun")

worker.py文件【子类1】

from  extends01.person import Person#2.定义子类
class Worker(Person):#构造函数【成员变量】def __init__(self,name,age,job):"""self.name = nameself.age = age"""self.job = job#6.在子类的构造函数中调用父类的构造函数【从父类中继承父类中的成员变量】#方式一:super(当前子类,self).__init__(属性列表)#super(Worker, self).__init__(name,age)#方式二:父类名.__init__(self,属性列表)Person.__init__(self,name,age)#方式三:super().__init__(属性列表)#super().__init__(name,age)#成员方法def work(self):print("work")

student.py文件【子类2】

from extends01.person import  Personclass Student(Person):# 构造函数【成员变量】def __init__(self, name, age, score):Person.__init__(self,name,age)self.score = score# 成员方法def study(self):print("study")

extendsDemo01.py文件【测试模块】

#测试模块
from extends01.person import Person
from extends01.worker import Worker
from extends01.student import Student#3.创建父类的对象
p = Person("zhangsan",10)
p.show()
#p.__fun()#4.创建子类的对象
w = Worker("aaa",20,"工人")
w.work()#5.子类对象访问父类中的内容
#结论一:子类对象可以调用父类中的公开的成员方法【因为继承,私有方法除外】
w.show()
#w.__fun()
#结论二:通过在子类的构造函数中调用父类的构造函数,子类对象可以直接访问父类中的成员变量【私有变量除外】
print(w.name,w.age,w.job)s = Student("小明",9,90)
s.study()
s.show()

2.2特殊用法:

子类中出现一个和父类同名的成员函数,则优先调用子类中的成员函数

s = Student("小明",9,90)
s.study()
s.show()

父类对象能不能访问子类中特有的成员函数和成员变量?----->不能

per = Person("gs",10)
#per.work()

slots属性能否应用在子类中
结论三:在父类中定义slots属性限制属性的定义,子类中是无法使用,除非在子类中添加自己的限制

#父类
class Student(object):__slots__ = ("name","age")#子类
class SeniorStudent(Student):passs  = Student()
s.name = "zhangsan"
s.age = 10
#s.score = 90ss = SeniorStudent()
ss.name = "lisi"
ss.age = 20
ss.score = 60

2.3 总结:

继承的特点:

​ a.子类对象可以直接访问父类中非私有化的属性

​ b.子类对象可以调用父类中非私有化的成员方法

​ c.父类对象不能访问或者调用子类 中任意的内容

继承的优缺点:

优点:

​ a.简化代码,减少代码的冗余

​ b.提高代码的复用性

​ c.提高了代码的可维护性

​ d.继承是多态的前提

缺点:

​ 通常使用耦合性来描述类与类之间的关系,耦合性越低,则说明代码的质量越高

​ 但是,在继承关系中,耦合性相对较高【如果修改父类,则子类也会随着发生改变】

3.多继承:

一个子类可以有多个父类

语法:

class 子类类名(父类1,父类2,父类3.。。。):

​ 类体

代码演示:

father.py文件【父类1】

class Father(object):def __init__(self,money):self.money = moneydef play(self):print("playing")def fun(self):print("father中的fun")

mother.py文件【父类2】

class Mother(object):def __init__(self,faceValue):self.faceValue = faceValuedef eat(self):print("eating")def fun(self):print("mother中的fun")

child.py文件【子类】

from extends02.father import Father
from extends02.mother import Mother#定义子类,有多个父类
class Child(Mother,Father):def __init__(self,money,faceValue,hobby):#调用父类中的构造函数Father.__init__(self,money)Mother.__init__(self,faceValue)self.hobby = hobbydef study(self):print("study")

extendsDemo03.py文件【测试模块】

from extends02.father import Father
from extends02.mother import Mother
from extends02.child import Childf = Father(100000)
m = Mother(3.0)#创建子类对象
c = Child(1000,3.0,"打游戏")
#子类对象调用父类中的成员方法
c.play()
c.eat()#结论;如果多个父类中有相同的函数,通过子类的对象调用,调用的是哪个父类中的函数取决于在父类列表中出现的先后顺序
c.fun()

4.函数重写【override】:

在子类中出现和父类同名的函数,则认为该函数是对父类中函数的重写

4.1 系统函数重写:

_str_
_repr_

class Animal(object):def __init__(self,name,age):self.name = nameself.age = age#重写__str__函数,重写之后一般return一个字符串,有关于成员变量def __str__(self):return "name=%s age=%d"%(self.name,self.age)#重写__repr__,作用和str是相同的,优先使用strdef __repr__(self):return "name=%s age=%d"%(self.name,self.age)a = Animal("大黄",10)
print(a)   #<__main__.Animal object at 0x00000226A87AC240>
print(a.__str__())#当一个类继承自object的时候,打印对象获取的是对象的地址,等同于通过子类对象调用父类中__str__
#当打印对象的时候,默认调用了__str__函数
#重写__str__的作用:为了调试程序

使用时机:当一个对象的属性有很多的时候,并且都需要打印,则可以重写__str__,可以简化代码,调试程序

4.2 自定义函数重写:

#函数重写的时机:在继承关系中,如果父类中函数的功能满足不了子类的需求,则在子类中需要重写
#父类
class People(object):def __init__(self,name):self.name = namedef fun(self):print("fun")#子类
class Student(People):def __init__(self,name,score):self.score = scoresuper(Student,self).__init__(name)#重写;将函数的声明和实现重新写一遍def fun(self):#在子类函数中调用父类中的函数【1.想使用父类中的功能,2.需要添加新的功能】#根据具体的需求决定需不需要调用父类中的函数super(Student,self).fun()print("fajfhak")s = Student("fhafh",10)
s.fun()

三、多态继承:

一种事物的多种体现形式,函数的重写其实就是多态的一种体现

在Python中,多态指的是父类的引用指向子类的对象

#父类
class Animal(object):pass#子类
class Dog(Animal):passclass Cat(Animal):pass#定义变量
a = []   #a是list类型
b = Animal()  #b是Animal类型
c = Cat()  #c是Cat类型#isinstance():判断一个对象是否属于某种类型【系统还是自定义的类型】
print(isinstance(a,list))
print(isinstance(b,Animal))
print(isinstance(c,Cat))print(isinstance(c,Animal))  #True
print(isinstance(b,Dog))   #False

结论:子类对象可以是父类类型,但是,父类的对象不能是子类类型

四、类方法和静态方法:

1.类方法:

类方法:使用@classmethod装饰器修饰的方法,被称为类方法,可以通过类名调用,也可以通过对象调用,但是一般情况下使用类名调用

class Test(object):
#1.类属性
age = 100def __init__(self,name):#2.实例属性self.name = name#3.成员方法,通过对象调用
#必须有一个参数,这个参数一般情况下为self,self代表是当前对象
def func(self):print("func")#4.类方法
"""
a.必须有一个参数,这个参数一般情况下为cls,cls代表的是当前类
b.类方法是属于整个类的,并不是属于某个具体的对象,在类方法中禁止出现self
c.在类方法的内部,可以直接通过cls调用当前类中的属性和方法
d.在类方法的内部,可以通过cls创建对象
"""
@classmethod
def test(cls):print("类方法")print(cls)   #<class 'methodDemo01.Test'>print(cls.age)#6#注意:cls完全当做当前类使用c = cls("hello")c.func()

2.静态方法:

静态方法:使用@staticmethod装饰器修饰的方法,被称为静态方法,可以通过类名调用,也可以通过对象调用,但是一般情况下使用类名调用

#1.静态方法
@staticmethod
def show():print("静态方法")t = Test("hjfsh")
t.func()#2.调用类方法
Test.test()   #类名.类方法的名称()
t.test()       #对象.类方法的名称()#3.调用静态方法
Test.show()
t.show()

3.总结:

实例方法【成员方法】、类方法以及静态方法之间的区别

a.语法上

​ 实例方法:第一个参数一般为self,在调用的时候不需要传参,代表的是当前对象【实例】

​ 静态方法:没有特殊要求

​ 类方法:第一个参数必须为cls,代表的是当前类

b.在调用上

​ 实例方法:只能对象

​ 静态方法:对象 或者 类

​ 类方法:对象 或者 类

c.在继承上【相同点】

​ 实例方法、静态方法、类方法:当子类中出现和父类中重名的函数的时候,子类对象调用的是子类中的方法【重写】

class SuperClass(object):
@staticmethod
def show():print("父类中的静态方法")@classmethod
def check(cls):print("父类中的类方法")class SubClass(SuperClass):
passs = SubClass()
s.show()
s.check()

注意:注意区分三种函数的书写形式,在使用,没有绝对的区分

五、类中的常用属性:

class Animal(object):
def __init__(self,arg):super(Animal, self).__init__()self.arg = argclass Tiger(Animal):
age = 100
height = 200def __init__(self,name):#super(Tiger, self).__init__(name)self.name = namedef haha(self):print("haha")@classmethod
def test(cls):print("cls")@staticmethod
def show():print("show")if __name__ == "__main__":

1.__name__

__name__
通过类名访问,获取类名字符串
不能通过对象访问,否则报错

#1.__name__
print(Tiger.__name__)  #Tigert = Tiger("")
#print(t.__name__)  #AttributeError: 'Tiger' object has no attribute '__name__'

__dict__
通过类名访问,获取指定类的信息【类方法,静态方法,成员方法】,返回的是一个字典
通过对象访问,获取的该对象的信息【所有的属性和值】,,返回的是一个字典

#2.__dict__
print(Tiger.__dict__)  #类属性,所有的方法
print(t.__dict__)   #实例属性

__bases__
通过类名访问,查看指定类的所有的父类【基类】

#3.__bases__,获取指定类的所有的父类,返回的是一个元组
print(Tiger.__bases__)

六、单例设计模式:

1.概念:

什么是设计模式

​ 经过已经总结好的解决问题的方案

​ 23种设计模式,比较常用的是单例设计模式,工厂设计模式,代理模式,装饰模式

什么是单例设计模式

​ 单个实例【对象】

​ 在程序运行的过程中,确保某一个类只能有一个实例【对象】,不管在哪个模块中获取对象,获取到的都是同一个对象

​ 单例设计模式的核心:一个类有且仅有一个实例,并且这个实例需要应用在整个工程中

2.应用场景:

实际应用:数据库连接池操作-----》应用程序中多处需要连接到数据库------》只需要创建一个连接池即可,避免资源的浪费

3.实现:

3.1 模块:

Python的模块就是天然的单例设计模式

模块的工作原理:

​ import xxx,模块被第一次导入的时候,会生成一个.pyc文件,当第二次导入的时候,会直接加载.pyc文件,将不会再去执行模块源代码

3.2 使用new:

new():实例从无到有的过程【对象的创建过程】

class Singleton(object):
#类属性
instance = None#类方法
@classmethod
def __new__(cls, *args, **kwargs):#如果instance的值不为None,说明已经被实例化了,则直接返回;如果为NOne,则需要被实例化if not cls.instance:cls.instance = super().__new__(cls)return cls.instanceclass MyClass(Singleton):
pass#当创建对象的时候自动被调用
one = MyClass()
two = MyClass()print(id(one))
print(id(two))print(one is two)

七、习题:

  1. 利用封装和继承的特性完成如下操作:

    小学生:
    属性:
    姓名
    学号
    年龄
    性别
    行为:
    学习
    打架

    中学生:
    属性:
    姓名
    学号
    年龄
    性别
    行为:
    学习
    谈恋爱

    大学生:
    属性:
    姓名
    学号
    年龄
    性别
    行为:
    学习
    打游戏

  2. 主人杨夫人 向客人 李小姐介绍自己家的宠物狗和宠物猫

    宠物狗:
    昵称是:贝贝
    年龄是:2
    性别:雌
    会两条腿行走的才艺

    宠物猫:
    昵称是:花花
    年龄是 1
    性别是:雄
    会装死的才艺

  3. 学生类:姓名、年龄、学号、成绩
    班级类:班级名称、学生列表
    显示所有学生
    根据学号查找学生
    添加一个学生
    删除一个学生(学生对象、学号)
    根据学号升序排序
    根据成绩降序排序

八、上期习题答案:

  1. 小美在朝阳公园溜旺财【注:旺财是狗】
class Person:def __init__(self, name):self.name = namedef play_dog(self, place):print(self.name, "在", place, "溜旺财")xiaomei = Person("小美")
xiaomei.play_dog("朝阳公园")

  1. 李晓在家里开party,向朋友介绍家中的黄色的宠物狗【彩彩】具有两条腿走路的特异功能。
class Person2:def __init__(self, name, dog):self.name = nameself.dog = dogdef exception(self, excep):print(f'{self.name}在家里开party,向朋友介绍家中的{self.dog.coloer}的宠物狗{self.dog.name}具有{excep}的特异功能。')class Dog:def __init__(self, name, coloer):self.name = nameself.coloer = coloerdog = Dog('【彩彩】', '黄色')
per = Person2('李晓', dog)
per.exception('两条脚走路')

  1. 王梅家的荷兰宠物猪【笨笨】跑丢了,她哭着贴寻猪启示。
class Person3:def __init__(self, name):self.name = namedef crry(self, findpig, pig):print(f'{self.name}家的{pig.where}宠物猪{pig.name}跑丢了,她哭着贴{findpig}')class Pig(Person3):def __init__(self, name, where):self.name = nameself.where = whereper3 = Person3('王梅')
pig = Pig('[笨笨]', '荷兰')
per3.crry('寻猪启示.', pig)

  1. 定义一“圆”(Circle)类,圆心为“点”Point类,构造一圆,求圆的周长和面积,并判断某点与圆的关系
    圆:
    属性: 半径,圆心
    方法: 周长,面积
    点:
    属性: x,y
# 圆
class Circle:def __init__(self, r, p):self.r = rself.p = pdef zhouchang(self):return 2 * self.r * 3.14def area(self):return self.r ** 2 * 3.14# 点
class Point:def __init__(self, x, y):self.x = xself.y = ydef relation_circle(self, circle):a = self.x - circle.p.xb = self.y - circle.p.yc = math.sqrt(a * a + b * b)if c > circle.r:print("在圆外")elif c < circle.r:print("在圆内")else:print("在圆上")# 对象
c = Circle(5, Point(3, 4))
p = Point(6, 8)p.relation_circle(c)

Python 学习笔记 类的封装 类的继承 多态继承 类方法和静态方法 单例设计模式相关推荐

  1. Python学习笔记:创建分数类

    Python学习笔记:创建分数类 1.编写创建分数类.py # 创建分数类from math import gcd# 定义分数类 class Fraction: def __init__(self, ...

  2. Python学习笔记__6.1章 类和实例

    # 这是学习廖雪峰老师python教程的学习笔记 1.概览 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一 ...

  3. Python学习笔记整理(十六)类的设计

    如何使用类来对有用的对象进行建模? 一.Python和OOP Python和OOP实现可以概括为三个概念. 继承     继承是基于Python中属性查找(在X.name表达式中) 多态     在X ...

  4. python学习笔记(七)——类基础

    前沿 问题一: 什么是类? 类是一个独立存放变量(属性/方法)的空间. 用来描述具有相同属性和方法的对象集合,它定义了该集合中每个对象所共同的属性和方法. 类是对象的抽象化,对象是类的实例化.类不代表 ...

  5. python学习笔记(八)类(classes)

    Python的类机制使用尽可能少的新语法和语义将类引入语言.python的类提供了面向对象程序设计语言所有的 标准特性:类继承机制允许有多个基类,一个派生类可以覆盖基类中的任何方法,一个方法可以使用相 ...

  6. python学习笔记(7)—— 类

    文章目录 类(Classes) 名称和对象(A Word About Names and Objects) python 作用域和命名空间 作用域和命名空间示例 初识类(A First Look at ...

  7. python学习笔记(七)类和面向对象

    目录 (一)了解面向对象 面向过程 面向对象的三大特性: (二)python中的类 1)定义类 新式类与经典类 2)初始化与实例化 3)类的属性 类属性与实例属性 私有属性 特殊属性 同名的类属性与实 ...

  8. Python学习笔记整理(十五)类的编写细节

    类代码编写细节 一.class语句 一般形式 class    <name>(superclass,...):     data=value     def mothod(self,... ...

  9. python学习笔记(六)——类的初始化(__init__)、类属性和类方法 和 对象

    学习本篇文章后会了解到:类的创建,为对象添加属性,对象的初始化,自定义对象的输出,类属性和类方法的创建. 1. 类的定义与格式 类是对一群具有相同特征或者行为的事物的一个统称. 类是一个模块,是负责创 ...

最新文章

  1. Tim Berners-Lee重新分散的新Web SOLID简介
  2. 漂亮的PCB设计图案
  3. Data Member 的存取
  4. MySQL学习笔记03【数据库表的CRUD操作、数据库表中记录的基本操作、客户端图形化界面工具SQLyog】
  5. 最强N皇后JAVA解题代码
  6. LoaderManager使用详解(一)---没有Loader之前的世界
  7. 自动点击器一秒200_做PPT还需要找模板?用这招3分钟就能自动排好PPT!
  8. 迁移 Docker 到其它磁盘目录
  9. 如何优雅的处理异常(java)
  10. Spring基础系列-AOP源码分析
  11. java从入门到入土_java从入门到入土---基础篇04---IO
  12. 基于springboot的mysql实现动态切换数据源
  13. 经典网络DenseNet介绍
  14. java ftps 证书_java – 连接到FTPS服务器
  15. 阿里云注册域名,购买云服务器,备案,域名解析图文教程
  16. dfuse 加入 BGA 区块链游戏联盟
  17. Linux隔离网络,linux – 隔离网络上的单个NTP服务器
  18. 基于小波变换的脉搏信号滤波matlab仿真
  19. 求最大公约数__gcd(a,b)
  20. There are multiple heroes that share the same tag within a subtree.

热门文章

  1. 最新的单片机_ST单片机近期连涨,比深圳的房价还快!
  2. 东师计算机教育综合,2021年东北师范大学学前教育专硕考研必看成功上岸前辈复习经验谈...
  3. 2020年学计算机需要什么配置,开学装机:2020年如何配一台5000元主流配置的游戏主机?...
  4. Merci上线Bit-M平台Accelerator
  5. 互联网手机的“围城” 有人想出去,有人想进去
  6. android studio 中文乱码,字体优化解决之道
  7. 【文本匹配】之 RE2论文详解
  8. 基于web的学生出国留学管理系统
  9. Visual Studio Professional 2015 激活密钥
  10. Android组件及UI框架大全