这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
一、背景
Python 语言相比Java , 抽象程度更高,更接近自然语言,容易上手,同样的功能Python代码量是最少的。
举个例子:
1.1 java示例
// 定义一个Student类
class Student {
// 定义一个名字属性
String name;
int age;
// 构造方法:带参
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 普通方法:无参
public void printInfo() {
System.out.println("我叫" + name + ",今年" + age + "岁");
}
// 普通方法:带参
public void printLike(ArrayList<String> likes) {
for (String like : likes) {
System.out.println("我的爱好是:" + like);
}
}
// 普通方法:带返回值
public String getName() {
return name;
}
}
class Test {
public static void main(String[] args) {
Student stu1 = new Student("张三", 18);
stu1.printInfo();
ArrayList<String> likes = new ArrayList();
likes.add("乒乓");
likes.add("篮球");
likes.add("足球");
stu1.printLike(likes);
// stu1.printLike("字符串"); // 编译报错
// Student stu2 = new Student(18,"张三"); // 编译报错
}
}
java的输出结果:
我叫张三 ,今年17岁
我的爱好: 乒乓
我的爱好: 篮球
我的爱好: 足球
1.2 python示例
# 定义一个Student类
class Student:
# 定义一个名字属性
name = None
age = None
# 构造方法:带参
def __init__(self, name, age):
self.name = name
self.age = age
# 普通方法:无参
def printInfo(self):
print("我叫" + self.name, ",今年" + self.age + "岁")
# 普通方法:带参
def printLike(self, likes):
for like in likes:
print("我的爱好:", like)
# 普通方法:带返回值
def getName(self):
return self.name
if __name__ == '__main__':
stu1 = Student("张三", "17")
stu1.printInfo()
stu1.printLike(["乒乓", "篮球", "足球"])
stu1.printLike("字符串")
stu2 = Student(17, "张三")
stu2.printInfo()
python的输出结果:
我叫张三 ,今年17岁
我的爱好: 乒乓
我的爱好: 篮球
我的爱好: 足球
我的爱好: 字
我的爱好: 符
我的爱好: 串
我叫17 ,今年张三岁
1.3 比较结果
1.3.1 java 特点
- 同样的功能,java代码量更多
- java必须以分号表示每段代码结束
- java 代码放在
{ }中 - 创建一个对象
new 类名(),必须要加new关键字 - 定义一个属性必须先指定具体类型
- 有返回值的普通方法必须指定返回类型
1.3.2 python 特点
- 同样的功能,python代码量更少
- python 代码 放在
:下面,并且要缩进 - 创建一个对象:
类名(),不需要new关键字 - 定义一个属性,直接声明即可,无需指定具体类型
- 方法声明只需要声明
def,即使有返回值也不需要声明返回类型 重要重要``重要方法中的参数是任意类型,调用方法时你可以传任意值,只要在方法体中不会报错,就能运行通过。所以上面printLike("字符串"),传的是字符串,方法体内部遍历的就是字符串,如果调用pringLike([])时传的是列表,方法体内部遍历的就是列表,也不会报错。从这点就可以看出,比Java更灵活,Java指定了参数类型后,只能传对应的类型。
1.3.3 总结
python 很简洁,但是牺牲了可读性,如:在java里,age属性预先指定了int 类型, 当 age = “李四”
,把字符串赋值给age的时候,编译就过不去。但是在python 里却可以这样赋值,所以python带来
了更高的灵活性,这种灵活性是语言的特点。
java 中方法如果没有返回值,返回类型必须什么void ,有返回值,必须指定返回类型。在python里,想返回就 return xx, 不想返回就直接 return 或者 不写return,果然很简洁。所以java 代码写起来是有始有终的,更加容易溯源。
二、面向对象简介
2.1 类(Class)
封装类相关的属性和方法 , 对象是类的实例。
# 定义一个Student类
class Student::
# 属性
name = ""
age = 0
# 方法
def eat(self):
pass
可以在Student 里定义 cartBrand = “” 属性吗? 可以的,但是这个属性和Student类没什么关系,大部分场景,我们在类中定义的属性都是和类有关系的。
stu1 = Student ()
stu1 是一个属性,是一个变量,指向了堆内存中的 Student() 对象,
2.2 方法 == 函数
2.2.1 方法类型有4种
def printInfo(self):
print("无参、无返回值、默认return可以省略")
return
def getName(self):
print("无参、有返回值")
return "刘德华"
def printName(self, name):
print("有参、无返回值、默认return可以省略")
return
def add(self, x, y):
print("有参、有返回值")
return x + y
2.2.2 方法中返回方法
def calc():
def add(x, y):
return x + y
return add
result = calc()
print(result) # 输出:<function calc.<locals>.add at 0x0000026F73425820>
print(result(3,4)) # 输出:7
2.3 变量 == 属性
2.3.1 类变量
class Student::
name = "" # 字符串
age = 0 # 数字
isMan = False # bool
likes = [ ] # 列表
likeEat = ( ) # 元组
map = { } # 字典
类变量定义在类中且在方法体之外 , 所有方法都可以通过self.变量 进行访问
2.3.2 方法变量也叫局部变量
def print()::
name = "" # 字符串
age = 0 # 数字
isMan = False # bool
likes = [ ] # 列表
likeEat = ( ) # 元组
map = { } # 字典
方法变量定义在方法内部,只有当前方法内部才能访问这些变量。
2.4 创建 == 实例化
class Student:
pass
stu1 = Student()
Student()相当java里的 new Student(); 意思是:创建一个Student对象,也可以说实例化``Student类
stu1 是 Student 类的对象,一个类可以被创建无数个对象
2.5 继承
class People:
def eat(self):
print("吃饭")
class Sport:
def playPP(self):
print("打乒乓球")
# 继承2个类
class Student(People,Sport):
pass
if __name__ == '__main__':
stu1 = Student()
stu1.eat() # 输出:吃饭
stu1.playPP() # 输出:打乒乓球
python 中 一个类可以继承多个类,People 和 Sport 是 Student 的父类, Student作为它们的子类,可以调用父类的方法。
2.6 方法重写
只有在继承的前提下,才有方法重写的说法。方法重写:子类定义1个方法,和父类方法名,方法参数一样
from abc import ABCMeta, abstractmethod
class People:
def eat(self):
print("吃饭")
@abstractmethod
def sleep(self):
pass
# 继承People
class Student(People):
# 重写父类的 sleep 方法
def sleep(self):
print("学生睡觉")
if __name__ == '__main__':
stu1 = Student()
stu1.sleep() # 输出:学生睡觉
三 多态
上图中的需求是:输出动物的名字。
3.1 实现步骤
- 创建User对象,
- 创建Dog对象,把对象传进User的
printAnimalName方法中。 - 创建Cat对象,把对象传进User的
printAnimalName方法中。
3.2 多态是一种思想
传入Dog对象,打印的是Dog的名字,传入Cat对象,打印的是Cat的名字。
为什么呢? 因为方法参数定义的是 animal,只要属于Animal类型的对象,都可以作为参数传进来。 后续有新的需求:打印猪、老虎的名字,User类下的printAnimalName方法都不需要改。
-
多态是一种思想
-
多态的前提必须得有继承
-
多态的前提必须得有方法重写
-
多态能提高可扩展性和可维护性
-
多态让父类引用指向子类对象,调用方法时会调用子类的实现,而不是父类的实现