因为python和java一样都是可以使用面向对象的编程思想的计算机语言,所以在python中也有面向对象编程的相关内容。那么什么是面向对象编程呢?所谓的面向对象编程就是我们可以创建一个对象来为我们完成任务,并且我们的程序并不需要严格的从上至下的去执行,如果出现对象的话,会先将对象所调用的方法执行之后再去执行之后的代码块(即使我们的对象的方法写在普通方法的后面)。与之相对的是面向过程编程思想,如c,vb等结构化的语言就是严格使用面向过程的编程思想。我们的python和Java也会使用到面向过程的编程,实际上,面向过程是计算机语言必备的编程思想,而面向对象的编程思想却是不一定的,主要还是看我们的项目需要的是什么功能的程序。
【面向对象关注的不是解决问题的过程,而是基于面向对象思想开发程序时会先分析问题,从中提取出多个对象,将不同对象各自的特征和行为进行封装,之后通过控制对象的行为解决问题。】
言归正传,现在我们去认识python中的面向对象编程的使用,中间可能会穿插一些Java中的面向对象的相关代码【主要是因为我先学的计算机语言是Java,所以每当我学一门新的计算机语言的时候总会拿新学到的语言和之前学过的语言进行对比,然后看一下它们的异同之处。】
目录
一,无初始化方法(构造方法),创建类
1,创建空类和实例方法并调用
2,与Java的比较
二,编写初始化对象的方法
1,使用__init__方法创建对象
2,与Java进行比较
三,类的成员
1,属性
1)实例去访问类属性
2)实例去修改类属性
3)类去访问实例属性
2,方法
1)类方法的定义和使用
2)使用类方法修改类属性
3)实例方法的定义和使用
4)静态方法的定义和使用
如果我们在使用一个类的时候不需要里面有什么属性的话,那么就可以去创建一个无__init__方法的类(即无对应的属性,也可以理解成使用的是默认的无参构造方法)。类里面可以去创建方法来给实例对象使用。
现在我们去创建一个类,并在里面创建两个类方法【类方法和普通方法不同,它必须且一定要在方法的参数列表第一个参数位置那里传入shelf参数,表示我们的方法为实例方法即什么对象去调用,shelf就表示什么对象(当前对象)的方法】
编程思想中有两个核心的概念:类和对象,其中对象映射了现实生活中真是存在的事物,它可以是具体的某样东西,房子,大树,桌子等,而我们的类可以理解成是制作这些具体存在的事物的设计图,是抽象的,不存在的,但是却是对象的模板,我们需要根据类去创建一个对象。
现在我们去使用代码看一下具体的使用和运行后的效果:
if __name__ == '__main__':
class MyClass:
pass # 一般是空类的时候需要用到,如果不是空类的话,也不会有影响
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(MyClass,cls).__new__(cls)
def add_two(shelf,a,b): # 创建实例带参方法
print(a+b)
def say_hello(self): # 创建实例无参方法
print("我是MyClass类")
myObject=MyClass() # 使用MyClass类创建实例
myObject.add_two(2022,1) # 实例对象使用带参方法
myObject.say_hello() # 实例对象使用无参方法
从上面我们可以看到:
如果我们使用Java语言来输出如上的信息的话,代码就会如下编写:
public class JavaTest {
public static void main(String[] args) {
MyClass myObject=new MyClass(); // 创建实例对象
myObject.add_two(2022, 1);
myObject.say_hello();
}
}
class MyClass{ // 默认调用无参构造方法
public static void add_two(int a,int b){ // 创建静态带参方法
System.out.println(a+b);
}
public static void say_hello(){ // 创建静态无参方法
System.out.print("你好,我是MyClass类");
}
}
上面的例子中,我们的类创建完成之后并不能给其添加一些属性和额外的操作,因为它使用的是默认的无参构造方法,里面没有任何属性的存在。如果我们想要后期在实例化对象时可以指定它对象的属性化就需要使用__init__方法。我们还可以对这个方法进行重载,即传入不同的参数。
现在我们去使用代码来查看具体的实现和运行效果:
if __name__ == '__main__':
class Student:
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self,name,age): # 带参构造方法
self.name=name # 表示属性值为当前对象的属性值相当于Java中的this关键字
self.age=age
def self_introduction(self): # 无参的实例方法
print(f"大家好,我的名字叫{self.name},今年{self.age}岁了")
student1=Student("张三",37) # 使用有参的构造方法创建对象
student1.self_introduction() # 对象调用实例方法
如上的语句我们也可以使用Java来得到:
public class JavaTest1 {
public static void main(String[] args) {
Student student =new Student("张三",37);
student.self_introduction();
}
}
class Student{
String name; // Java中需要先设置类的属性
int age;
public Student(String name,int age){
this.name=name; // 表示为调用对象的属性值
this.age=age;
}
public void self_introduction(){
System.out.printf("大家好,我的名字叫%s,今年%d岁了",this.name,this.age);
}
}
如上,我们可以看到,相比于Java这一大串的代码(对象实例化,属性声明定义,指定属性类型等),python要显得简洁方便很多。
类的成员包括属性和方法,默认它们是共有的,可以在类的外部被访问或者是调用的,但是有些时候为了数据的安全问题,我们需要将其设置为私有成员,限制类外部对其进行访问或者是调用。
接下来我们去学习python中的属性,方法和私有成员这三个内容:
属性按声明的方式可以分为两类:类属性和实例属性。
接下来我们通过代码来看一下它们具体的使用:
if __name__ == '__main__':
class Student:
string2="hello class" # 类属性
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
student=Student() # 使用Student类创建student对象
print(student.string2) # 使用实例对象访问类属性(定义在所有方法外,类体内的属性)
print(Student.string2) # 使用类访问类属性
我们可以看到,程序没有报错,代表我们是可以通过实例去访问类属性的,但是如果我们想要去修改的话就会发现实例对象是无法修改类属性的:
if __name__ == '__main__':
class Student:
string2="hello class" # 类属性
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
student=Student() # 使用Student类创建student对象
print(student.string2) # 使用实例对象访问类属性(定义在所有方法外,类体内的属性)
print(Student.string2) # 使用类访问类属性
student.string2="hello i(实例对象) can modify" # 使用实例对象来修改类属性
print(Student.string2) # 使用类访问类属性
print(student.string2) # 使用实例对象访问类属性(定义在所有方法外,类体内的属性)
如上,我们使用实例对象去修改类属性后,类属性的值依旧为“hello class”。
相信大家也发现了,我们使用实例对象去访问的时候却是修改后的结果“hello i(实例对象) can modify”,那是因为什么呢?那是因为python支持在类的外部使用对象动态的添加实例属性。如下,我们使用对象动态的添加类中没有的score实例属性:
if __name__ == '__main__':
class Student:
string2="hello class" # 类属性
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
student=Student() # 使用Student类创建student对象
print(student.string2) # 使用实例对象访问类属性(定义在所有方法外,类体内的属性)
print(Student.string2) # 使用类访问类属性
student.string2="hello i(实例对象) can modify" # 使用实例对象来修改类属性
print(Student.string2) # 使用类访问类属性
student.score=666
print(student.string2) # 使用实例对象访问类属性(定义在所有方法外,类体内的属性)
print(student.score) # 访问对象动态添加的实例
如上,程序成功添加了实例属性,并通过对象访问了新增加的实例属性。
对于类来说,类是不可以去访问实例属性的,且不能进行相应的修改。
if __name__ == '__main__':
class Student:
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
def say_hello(self):
self.string1="hello world!" # string1为实例属性
student=Student() # 使用Student类创建student对象
print(student.string1) # 使用实例对象访问实例属性(定义在__init__方法中的属性)
print(Student.string1) # 使用类访问实例属性
如上,程序报错,并告诉我们在类里面没有string1属性,即我们的实例属性不是它所能够进行访问和修改的类属性,所以类是无法访问我们的实例属性的(既然连访问的资格都没有,更遑论去修改),这个在Java中也一样,类无法去访问并修改实例属性。
上面我们知道了属性是有类属性和实例属性之分的,我们的方法也不例外,也有类方法和实例方法之分。现在我们来认识与了解它:
类方法和我们的类属性一样,都是需要声明在各方法外部,类的内部的。但是类方法多个装饰器@classmethod,如下:
if __name__ == '__main__':
class Student:
@classmethod # 使用装饰器修饰的类方法
def class_method(cls):
print("我是个类方法\n")
string2="hello class" # 类属性
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
student=Student() # 使用Student类创建student对象
student.class_method() # 使用实例对象调用类方法
Student.class_method() # 使用类调用类方法
从上面的结果可以看出,程序通过实例对象和类都可以成功调用类方法。
我们的类方法可以像类那样,访问并修改类属性。例如现在我们在类Student中添加age属性,并赋值20,之后再通过类方法中的cls(类本身)进行修改和访问。
if __name__ == '__main__':
class Student:
age=20 # 类属性
@classmethod # 使用装饰器修饰的类方法
def class_method(cls):
print("我是个类方法\n")
print(f"修改前的类属性age:{cls.age}") #修改前的age
print("我可以修改类属性,正在修改类属性中......")
cls.age=18 # 使用cls访问和修改类属性
print(f"修改后的类属性age:{cls.age}") #修改后的age
string2="hello class" # 类属性
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
student=Student() # 使用Student类创建student对象
student.class_method() # 使用实例对象调用类方法
Student.class_method() # 使用类调用类方法
如上,我们看到,当我们使用实例对象或者是类来调用类方法对我们的类属性进行修改时,之前的类属性值还是20,修改之后才变成了18。
实例方法和类方法不一样,它不需要使用@classmethod修饰器来修改我们的方法,它其实和普通的方法类似,但是它的第一个参数必须是self,代表对象的本身,它会在实例方法被调用的时候自动接收由系统传递的调用该方法的对象,之前我们也发现了,类属性和类方法都是可以使用类和实例来进行访问的,但是实例属性却只能通过实例对象来访问。我们的实例方法也不例外,它和实例属性一样,只能通过实例对象来访问和修改。
if __name__ == '__main__':
class Student:
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
def say_hello(self): # 定义实例方法
print("hello man,keep coding!")
student=Student() # 使用Student类创建student对象
student.say_hello() # 实例对象调用实例方法
Student.say_hello() # 类调用实例对象
所以,我们现在知道了类是不能去调用实例方法的,就像之前的实例属性一样。
静态方法和类方法类似,它们都需要使用特定的装饰器来修饰对应的方法。
而我们的静态方法使用的是@staticmethod装饰器来进行修饰,与我们的实例方法和类方法相比,静态方法没有任何默认参数,如实例方法需要有第一个参数self,静态方法需要有第一个形参cls。静态方法适用与类无关的操作或者是无须使用类成员的操作。
例如我们简单的使用一个静态方法来输出打印字符串”hello world“并打印出来相应的类属性或者是调用类方法,如下:
if __name__ == '__main__':
class Student:
age=20
def __new__(cls, *args, **kwargs): # 创建实例化对象的方法
return super(Student,cls).__new__(cls)
def __init__(self):
pass # 空参构造方法
@staticmethod # 修改静态方法
def do_something(): # 无参的方法
print(f"我是静态方法,我所在类的age类属性值为{Student.age}")
student=Student()
student.do_something() # 调用静态方法
如上,虽然我们的静态方法内部不能直接访问属性或者是方法,但是使用类名访问类属性或者是方法。
以上就是python面向对象编程的内容,有问题请在评论区留言。