文章目录
- 一、修饰符
- 1. 权限修饰符
- 2. 状态修饰符
- 2.1 final
- 2.2 static
- 二、多态
- 1. 成员访问特点
- 2. 多态中的转型
- 3. 多态案例
一、修饰符
1. 权限修饰符
2. 状态修饰符
2.1 final
final 关键字是最终的意思,可以修饰成员方法、成员变量及类。
//1.修饰成员变量
public final int age = 20; //age的值不允许再改变
//2.修饰成员方法
public final void method() {} //该方法不允许被重写
//3.修饰类
public final class Father {} //该类不允许被继承
final 修饰的特点:
① 修饰方法,表明该方法是最终方法,不能被重写;
② 修饰变量,表明该变量是常量,不能再次被赋值;
③ 修饰类,表明该类是最终类,不能被继承。
final 修饰的是基本类型的变量时,变量的数据值不能发生改变,当 final 修饰引用类型的变量时,变量的地址值不能发生改变,但地址里面的内容是可以改变的!
2.2 static
static 关键字是静态的意思,可以修饰成员方法和成员变量。
//Student.java
public static String university;
//Test.java
Student.university = "太原理工大学"; //直接通过类名为所有对象的公共部分赋值
static 修饰的特点:
① 被类的所有对象共享,这也是我们判断是否使用静态关键字的条件;
② 被 static 修饰的变量和方法,可以通过对象名调用,也可以直接通过类名来调用,推荐使用类名调用。
静态成员方法只能访问静态成员,即 static 只能访问 static!
二、多态
多态,同一个对象在不同时刻表现出来的不同形态。
举例:
我们可以说米是米,米 rice = new 米();
我们也可以说米是粮食,粮食 food = new 米();
这里米在不同的时刻就表现出来了不同的形态,这就是多态。
多态的前提和体现:
① 有继承或者实现关系;
② 有方法重写;
③ 有父类引用指向子类对象。
1. 成员访问特点
Animal a = new cat();
System.out.println(a.age);
System.out.println(a.eat());
(1)Cat 类继承 Animal 类,不管是访问 a 的成员变量还是成员方法,程序都会先去 Animal 里面找,如果找不到该变量或方法,程序直接报错,即编译看左边。
(2)如果我们访问的是成员变量 a.age,同时在 Animal 类中也找到该变量时,我们所访问到的 age 也正是 Animal 中的 age,即访问成员变量执行看左边。
(3)如果我们访问的是成员方法 a.eat(),同时在 Animal 类中也找到该方法时,我们此时访问到的 eat() 应是 Cat 类中重写父类方法的 eat(),即访问成员方法执行看右边。
2. 多态中的转型
① 多态的好处:提高了程序的扩展性,定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作;
② 多态的弊端,不能使用子类特有的功能,因为编译看左边,当多态访问成员变量或方法的时候,都是先去父类中寻找的,而父类中当然没有子类特有的功能,当它找不到的时候编译就会报错。
针对多态的弊端,有什么解决办法呢?
多态转型分为向上转型和向下转型,向上转型即父类引用指向子类对象,向下转型是父类引用转为子类对象。
我们通过向下转型的方法解决不能使用子类特有功能的问题。
Animal a;
//向下转型
a = new Cat();
Cat c = (Cat)a;
c.playGame();
//向上转型
a = new Dog();
a.eat();
3. 多态案例
//Animal.java
package com.zxe;
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("动物吃东西!");
}
}
//Cat.java
package com.zxe;
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫爱吃鱼!");
}
public void call() {
System.out.println("喵喵喵~");
}
}
//Dog.java
package com.zxe;
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗爱吃骨头!");
}
}
//Test.java
package com.zxe;
public class Test {
public static void main(String[] args) {
//这里仅以Cat为例,Dog同理
Animal a = new Cat();
a.setName("加菲猫");
a.setAge(5);
System.out.println(a.getName() + ", " + a.getAge());
a.eat();
//想要用Cat的特有方法,向下转型即可
Cat c = (Cat) a;
c.call();
}
}