【Java基础】 面向对象
程序员文章站
2024-01-20 22:39:52
...
介绍
在 Java 中,类的具体表现或者实例就是对象,而对象的抽象形式就是类。
举个简单的例子:比如我说“动物”,你脑海中浮现的是什么?有具体的样子吗?可能你会想到各种各样的动物,但其实你只是想到了它们的共同特征:会跑、会跳等。但是如果我说“小狗”,你是不是马上就想到了小狗的样子:用四条腿走路,跳跃,汪汪叫。
这里的“动物”就是指的抽象的“类”,而“小狗”则是指的类的实例“对象”。
三大特征
1. 封装(Encapsulation)
顾名思义,封装就是把数据和操作封装起来,使其成为一个独立的实体。数据被保护起来,内部细节被隐藏,只保留一些对外的接口和外界交互。
2. 继承(Inheritance)
继承实现了 IS-A 关系,例如 Cat 和 Animal 就是一种 IS-A 关系,Cat 继承了 Animal 除 private 修饰以外的所有的成员。
名称 | 说明 | 备注 |
---|---|---|
public | 可以被任何类访问 | |
protected | 可以被同一包中的所有类访问 可以被所有子类访问 |
子类没有在同一包中也可以访问 |
缺省\无访问修饰符 | 可以被同一包中的所有类访问 | 如果子类没有在同一个包中, 则不能访问 |
private | 只能够被当前类的方法访问 |
3. 多态(Polymorphism)
用一句话概括就是:事物在运行过程中存在不同的状态。
三个条件:
- 要有继承关系
- 子类要重写父类的方法
- 向上转型 (
Animal animal = new Cat();
)
先来看一个例子:
首先定义两个类,一个父类Animal,一个子类Cat。
class Animal {
String name = "我是动物";
static int age = 20;
public void eat() {
System.out.println("动物可以吃饭");
}
public static void sleep() {
System.out.println("动物可以睡觉");
}
public void run(){
System.out.println("动物可以奔跑");
}
}
class Cat extends Animal {
String name = "小猫";
static int age = 10;
public void eat() {
System.out.println("小猫可以吃饭");
}
public static void sleep() {
System.out.println("小猫可以睡觉");
}
public void catchMouse() {
System.out.println("小猫可以捉老鼠");
}
}
测试方法:
public static void main(String[] args) {
Animal am = new Cat();
am.eat();
am.sleep(); // 严格来所应该使用 Animal.sleep(),这里是为了方便理解
am.run();
System.out.println(am.name);
System.out.println(am.age); // 同上,Animal.age
}
输出:
小猫可以吃饭 // 重写非静态方法
动物可以睡觉 // 重写静态方法
动物可以奔跑 // 未重写方法
我是动物 // 成员变量
20 // 静态变量
出现这样的结果是因为多态的特点:
- 成员变量,编译看父类,运行看父类
- 成员方法,编译看父类,运行看子类
- 静态方法,编译和运行都是看父类
只有非静态的成员方法,编译看父类,运行看子类。
多态有一个不好的地方就是不能访问子类特有的属性和方法。在上面的例子中,子类 Cat 有一个特有的方法 catchMouse()
, 但是使用多态后就不能访问该方法,会报错。
如果需要使用子类中特有方法就必须向下转型。
Cat cat = (Cat) am;
cat.catchMouse();
参考文章:JAVA的多态用几句话能直观的解释一下吗? - 程序狗的回答 - 知乎
https://www.zhihu.com/question/30082151/answer/120520568