python-面向对象

目录

面向对象

封装

继承

重写

 重载

多态

单下划线、双下划线、头尾双下划线说明:


面向对象

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

# 创建类  Stuent是类名 包含name和age两个属性
class Stuent:
    name=None
    age=0

# stu是Stuent类变量,也就是对象
stu=Stuent()

#通过对象引用类属性
stu.age=18
stu.name="张三"

print("stu.name ",{stu.name },"stu.age",{stu.age})

成员方法

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。

  • self 代表类的实例,self 在定义类的方法时是必须有的,但是调用时不必传入相应的参数。

  • self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类,通过self可以调用类的属性
  • self 不是 python 关键字,我们把它换成其他变量也是可以正常执行的

# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    def printf(self,name,age):
       print(self)
       self.name=name
       self. age=age
       print("name ", {self.name}, "age", {self.age},"self.__class__",self.__class__)

stu=Student()
stu.printf("张三",18)

构造方法

 __init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法

python里一个class不可以定义多个构造函数,一个class只能有一个用于构造对象的__init__函数,这时,可以使用不定长参数接收多个参数

析构函数 __del__ ,__del__在对象销毁的时候被调用,当对象不再被使用时,__del__方法运行


# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    # 成员方法
    def printf(self):
       print(self)
       print("name ", {self.name}, "age", {self.age},"self.__class__",self.__class__)
    # 构造方法
    def __init__(self,name,age):
        self.name=name
        self.age=age

stu=Student("张三",18)   #创建对象 调用构造方法
stu.printf()

 内置方法

一个类中,包含了多种内置方法,实现了不同的功能,称为魔术方法

1、字符串转换:控制类对象的转化

正常打印类对象时,得到的是类变量的内存地址

 str方法:返回自定义字符串,执行此类对象的print方法,自动调用str方法

# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    # 成员方法
    def printf(self):
       print(self)
       print("name ", {self.name}, "age", {self.age},"self.__class__",self.__class__)
    # 构造方法
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return f"Student变量: name={self.name},age={self.age}"
stu=Student("张三",18)   #创建对象 调用构造方法
print(stu)

 2、lt:小于比较

直接对两个类对象,进行比较是不可以的。要通过lt方法制定比较规则


# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    # 构造方法
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return f"Student变量: name={self.name},age={self.age}"
    def __lt__(self, other):
        return self.age<other.age

stu=Student("张三",18)   #创建对象 调用构造方法
stu1=Student("张三",18)   #创建对象 调用构造方法
print(stu<stu1)


3、le:小于等于比较


# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    # 构造方法
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return f"Student变量: name={self.name},age={self.age}"
    def __le__(self, other):
        return self.age<=other.age

stu=Student("张三",18)   #创建对象 调用构造方法
stu1=Student("张三",18)   #创建对象 调用构造方法
print(stu<=stu1)


4、eq方法:判断是否相等

不重写eq方法,默认比较的是两个对象的内存地址,肯定不相等


# Student类包括两个成员属性 name和age,还包括一个成员方法
class Student:
    name=None
    age=0
    # 构造方法
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return f"Student变量: name={self.name},age={self.age}"
    def __eq__(self, other):
        return self.name==other.name

stu=Student("张三",10)   #创建对象 调用构造方法
stu1=Student("张三",18)   #创建对象 调用构造方法
print(stu==stu1)


关系运算是比较2个对象,包括:

关系运算含义
__lt__X<Y
__gt__X>Y
__le__X<=Y
__ge__X>=Y
__eq__X==Y
__ne__X!=Y
__cmp__比较X和Y,用于sorted,返回值是-1,1,0

面向对象有三大特征:封装、继承、多态

封装

封装:将现实中的事物转化为类

私有属性,只可以在类中被使用,在其余地方都无法使用


class Student:
    __age=10  #age是私有变量
    __name="张三"  #name是私有变量
    def __printf(self): #私有方法 对象不可以调用此方法
        print("name ", {self.__name}, "age", {self.__age})
    def init(self):  #公开方法
        self.__printf()
stu=Student()
stu.init()

继承

子类继承父类,得到父类的公开属性

python支持多继承:一个子类可以继承多个父类,如果多个父类中包含了同名属性,以左侧的父类为准

class Aniaml:
    name=None
    __age=0
    def eat(self):
        print(self.name+"正在吃东西")

#Bird类继承了Aniaml父类,得到了Aniaml类的公开属性
class Bird (Aniaml):
    def fly(self):
        print("鸟在飞")


bird =Bird()
bird.name="糖豆"
bird.fly()
bird.eat()

在python中继承中的一些特点:


  1. 子类不重写 __init__,实例化子类时,会自动调用父类定义的 __init__。
  2. 子类重写了__init__ 时,实例化子类,就不会调用父类已经定义的 __init__
  3. 子类重写了__init__ 时,要使用父类的构造方法,可以使用 super 关键字,语法:super(子类,self).__ init __(参数);也可以使用如下格式调用:父类名.__init__(self, 参数列表

这里和java不一样的是,java是子类先帮父类构造,如果父类只包含无参的构造方法,创建子类对象会自动先调用父类无参的构造方法,如果父类存在包含参数的构造方法,就要使用super关键字显示调用


class A:
    age=0
    def __init__(self,*args):
        self.age=args[0]
        print("父类A的有参构造方法",{self.age})
        print("离开父类的有参构造方法")

class B (A):
    def __init__(self,age):
       print("子类B的构造方法")
       super(B, self).__init__(age)
       print("离开子类B")

class C(B,A):  #这里不是A,B这样的传参顺序,是因为B类继承了A类,如果是A,B顺序,先创建A对象,创建B对象也会创建A对象,python不允许这样
    def __init__(self, age):
        super(C, self).__init__(age)
        print("子类C的构造方法")
        print("离开子类C")
C(10)

  • 2、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)

重写

子类可以对父类方法重写,调用时执行重写后的方法


class Aniaml:
    name=None
    __age=0
    def eat(self):
        print(self.name+"正在吃东西")

#Bird类继承了Aniaml父类,得到了Aniaml类的公开属性
class Bird (Aniaml):
    def fly(self):
        print("鸟在飞")

    def eat(self):  #对父类的这个方法进行重写
        print("有一只鸟正在吃东西")

bird =Bird()
bird.fly()
bird.eat()

 super关键字:在子类中调用父类属性

super().成员变量

super().成员方法()

 重载

Python 是一种动态语言,不需要声明变量类型。该函数可以接受任何类型的参数,因此不支持根据参数类型进行重载。但是可以支持运算符重载

python支持运算符如下:

 


class A:
    def __init__(self,x,y):
        self.x=x
        self.y=y

    def __str__(self):
        return  f"x={self.x},y={self.y}"
    def __sub__(self, other):
        return A(self.x-other.x,self.y-other.y)
a=A(1,2)
b=A(3,6)
print(a.__sub__(b))   # 1-3=-2   2-6=-4

多态

在完成某一个行为时,通过不同的对象,执行不同的方法

class AC:
    def ac(self):
        pass

pass关键字起到占位符的作用,ac方法没有方法体,pass是为了让ac方法符合语法规定添加的。

这样没有方法体的方法称为抽象方法,包含抽象方法的类就是抽象类

抽象类是要被继承的,子类要重写抽象父类的抽象方法


class AC:
    def ac(self):
        pass
class A (AC):
    def ac(self):
        print("A子类重写父类AC的ac方法")
class B (AC):
    def ac(self):
        print("B子类重写父类AC的ac方法")

def printf(tmp :AC):
    tmp.ac()
printf(A())
printf(B())

printf方法的执行,取决于参数tmp的实际类型

tmp是A类型,它实际上拥有自己的 ac()方法。调用 tmp.ac()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

python是动态类型的语言,所以,传递给函数 printf(tmp)的参数tmp 不一定是 AC 或 AC 的子类型。任何数据类型的实例都可以,只要它有一个ac()的方法即可

单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。

  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值