因为我之前学过Java,所以下文中的python面向对象知识点会和Java面向对象知识点比较记忆;
python类的定义
python类的定义个其函数的定义格式相同,为此先复习函数定义格式:
def add(num1, num2){
return num1 + num2
}
类定义格式:类的定义时类名后面没有括号,当然也可以添加括号,用于类的继承,后面会说:
class User:
name = None,
age = None,
def speak(self):
print("我在说话")
def eat(self):
print("我在吃饭")
user1 = User()
类的组成
python类的组成和Java相似,都有属性、方法、私有属性、私有方法、构造方法等等;
属性和方法没的说,我们只简单的提一下他们如何调用:
class User:
name = "zhangsan",
age = 23,
gender = "男",
def printname(self):
print(self.name)
user = User()
user.printname()
print(user.age)
这里的代码中提到了self,是什么呢?
self
其实python中的self和java中的this一样,都是值当前对象本身,我们可以通过self在成员方法了内部调用成员变量;
//Java代码(this)
public void setRadius(double radius) {
this.radius = radius;
}
# python代码(self)
class User:
name = "zhangsan",
age = 23,
gender = "男",
def printname(self):
print(self.name)
构造方法
python中这点和java一样,类都有构造器,只不过构造方法的名字取值方式不一样;java中构造方法的名字必须和类名一致,而Python的构造方法名是固定的def __init__(self):;还有一点就是虽然你的构造方法名是__init__但是你创建对象的时候,仍然使用的类名加()案例如下;
class User:
name = None,
age = None,
gender = None,
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
user2 = User("lisi", 34, "nv" )
在python中如果你不显示的给出构造方法,python底层会为你隐式的给出一个无参构造法方法:
but 一旦你显式的给出含参构造方法,那么就不能直接无参的创建对象了,python中无参和有参构造只能存一个;这点和java有区别,java是同时无参和含参构造函数存在,但是python不一样,要注意;
class User:
name = None,
age = None,
gender = None,
def __init__(self, ):
pass
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
user = User()
最后一行代码会报错:
TypeError: User.__init__() missing 3 required positional arguments: 'name', 'age', and 'gender'
上述代码中虽然有无参构造和含参构造,但其实后面的构造方法将前面的构造方法覆盖了,因此只能存在一个构造方法;
在 Python 中,构造函数 __init__(self) 只能有一个,并且它必须至少带有一个 self 参数。如果你想定义一个有参构造函数,你需要在该方法中显式地定义所需的参数。如果你想定义一个无参构造函数,你需要定义一个仅带有 self 参数的 __init__ 方法。当然你什么都不给,系统会为你默认给出无参构造方法;
def __init__(self):
pass
私有属性和私有方法
python和java一样都支持私有化属性或者方法,但Java采用的是给变量添加关键字private,如下列代码:
private static double pi = 3.14;
private double radius;
而python是通过变量名和方法名的格式来判断是否是私有化的,例如如果你需要将一个属性或者方法变成私有化的,就在其变量名之前加__两个下划线,案例如下:
class User:
__name = None,
__age = None,
__gender = None,
user = User()
print(user.__age) #报错
最后一句代码就会报错:
AttributeError: 'User' object has no attribute 'age'
当然你可以在类的方法中使用self调用私有属性如下:
class User:
__name = None,
__age = None,
__gender = None,
def printname(self):
print(self.__name)
user = User()
user.printname()
这段代码是正常的;
继承
python中支持多继承吗?
是的,Python语言支持多继承。所谓多继承,即一个类可以同时从多个父类中继承属性和方法。
在Python中,如果需要创建一个类并从多个父类中继承,可以使用如下的语法:
class ChildClass(ParentClass1, ParentClass2, ...):
在这个定义中,ChildClass称作子类,ParentClass1、ParentClass2等则称作父类。子类会继承所有父类的属性和方法,并可以根据需要添加自己的属性和方法。
当子类继承了多个父类时,如果有父类之间存在同名方法或属性,Python会按照一定的算法来确定优先级。Python通过使用C3算法来解决多继承时的方法解析顺序(MRO)问题,确保每个方法只被调用一次,并且保证继承顺序对方法解析的影响最小化。
虽然多继承可以方便地重用代码,但也可能会导致设计上的复杂性和混乱。因此,在使用多继承时,应该根据实际情况进行权衡,并尽量避免过度使用;
子类调用父类的成员
在学习了python的继承知识点之后,随之而来的就是python的继承中的复写,即父类的方法并不能够完全提供子类的使用场景,或者子类想要扩展父类的方法的能力,所以子类会重写父类的方法或者属性;这点和Java一样,就不赘述了;
当我们继承了父类的属性和方法之后,我们还能不能在子类中调用父类中的方法或者属性呢;有,子类调用父类的属性或者方法有两种实现方式:
-
通过父类名点的方式来调用父类
-
父类名.成员属性
-
父类名.成员方法(self)
-
-
使用super()函数
-
super().成员变量
-
super().父类方法( )
-
-
注意,我们只能在子类的内部调用父类的同名成员,子类的实体类对象调用的默认是调用子类复写的成员;
抽象类
Python中的抽象类是指不能被实例化的类,其作用是为子类提供接口和规范。具体来说,抽象类定义了一组方法名,但没有具体实现,而子类必须实现这些方法才能被实例化。
为什么会有抽象类呢?有时我们希望父类并不给出方法的具体实现时,具体实现给到子类让子类书写时,就会有抽象类,
- 父类知识缺点有哪些方法;
- 具体实现给子类自行决定;
案例:
class Animal:
def speak(self):
pass
def eat(self):
pass
class dog(Animal):
def speak(self):
print("hhhh")
class cat(Animal):
def speak(self):
print("mmmm")
课堂笔记: