多态
多态就是某一个事物,在不同时刻表现出来的不同状态。
前提是要有继承关系,方法重写,没有也可以,但是就没有意义了。
举例:
Aniaml a = new Cat();
猫可以是猫类型,同时猫也是动物的一种,也可以把猫称为动物。
其实就是父类引用指向子类对象。
父 f = new 子();
多态中的成员访问特点
成员变量:编译看左边,运行看左边。
构造方法:创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
成员方法:编译看左边,执行看右边。(当没有重写时,去父类找)
静态方法:编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问还是左边的)
案例演示
class Fu {
int n = 10;
Fu() {
System.out.println("父类构造方法");
}
public void show() {
System.out.println("Fu show");
}
public static void set(){
System.out.println("静态方法");
}
}
class Zi extends Fu {
int n = 20;
Zi() {
System.out.println("子类构造方法");
}
@Override
public void show() {
System.out.println("Zi show");
}
}
public class Test {
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.n);
f.show();
f.set();
}
}
运行结果
抽象类
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
特点:
抽象类和抽象方法必须用abstract关键字修饰。
抽象类格式:abstract class 类名 {}
抽象方法格式: public abstract void eat();
抽象类中可以有构造方法,用于子类访问父类数据时的初始化,抽象类不能直接进行实例化,按照多态的方式,由具体的子类实例化。
抽象类的子类,要么是抽象类,要么重写抽象类中的所有抽象方法。
案例演示:
abstract class Animal {
String name;
int age;
public void sleep() {
System.out.println("睡觉");
}
public abstract void eat();
}
class Cat extends Animal {
String name = "汤姆";
int age = 4;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal {
String name = "旺财";
int age = 6;
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.name);
System.out.println(cat.age);
cat.eat();
cat.sleep();
System.out.println("------------------");
Dog dog = new Dog();
System.out.println(dog.name);
System.out.println(dog.age);
dog.eat();
dog.sleep();
}
}
运行结果
接口
Java中提供了接口来定义一些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
特点
接口用关键字interface表示 格式:interface 接口名 {}
类实现接口用implements表示 格式:class 类名 implements 接口名 {}
接口不能实例化,按照多态的方式来实例化。
接口的子类,可以是抽象类。但是意义不大。也可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
接口的成员变量有默认修饰符:public static final 所以是常量,并且是静态的。
接口没有构造方法,而且成员方法只能是抽象方法,默认修饰符:public abstract
案例演示
/*
传智播客的老师有基础班的,也有就业班的。
共性:
属性:姓名,年龄
功能:讲课。
现在又要针对日语这种小语种单独开班,
需要部分基础班老师和部分就业班老师会说日语。
*/
abstract class Teacher {
String name;
int age;
public abstract void Teach();
}
class BaseTeacher extends Teacher {
@Override
public void Teach() {
System.out.println("基础班");
}
}
class EmployTeacher extends Teacher {
@Override
public void Teach() {
System.out.println("就业班");
}
}
interface Janpanese {
void SpeakJa();
}
class MrLI extends BaseTeacher {
@Override
public void Teach() {
super.Teach();
}
}
class MrWang extends BaseTeacher implements Janpanese {
@Override
public void SpeakJa() {
System.out.println("王老师会说日语");
}
}
class MrZhang extends EmployTeacher {
@Override
public void Teach() {
super.Teach();
}
}
class MrZhao extends EmployTeacher implements Janpanese {
@Override
public void SpeakJa() {
System.out.println("赵老师会说日语");
}
}
public class Test {
public static void main(String[] args) {
System.out.println("传智播客的老师");
Teacher teacher = new MrWang();
teacher.name = "王老师";
teacher.age = 33;
System.out.println(teacher.name);
System.out.println(teacher.age);
teacher.Teach();
((MrWang) teacher).SpeakJa();
System.out.println("-----------------");
teacher = new MrZhao();
teacher.name = "赵老师";
teacher.age = 35;
System.out.println(teacher.name);
System.out.println(teacher.age);
teacher.Teach();
((MrZhao) teacher).SpeakJa();
System.out.println("-----------------");
teacher = new MrZhang();
teacher.name = "张老师";
teacher.age = 44;
System.out.println(teacher.name);
System.out.println(teacher.age);
teacher.Teach();
System.out.println("-----------------");
teacher = new MrLI();
teacher.name = "李老师";
teacher.age = 37;
System.out.println(teacher.name);
System.out.println(teacher.age);
teacher.Teach();
}
}
来源:https://blog.csdn.net/weixin_45422954/article/details/102743539