面向对象特征之一:多态,即事物存在的多种形态
多态的前提:要有继承关系,要有方法重写,要有父类引用指向子类对象
多态中的成员访问特点:成员变量编译时看左边,运行看左边
成员方法编译看左边,运行看右边
静态方法编译看左边,运行看左边
多态可提高代码的维护性和扩展性,可以当作形式参数,可以接收任意子类对象,不能使用子类的特有属性和行为
抽象类:抽象类和抽象方法必须要用abstract关键字修饰
abstract class 类名{}
public abstract void eat();
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
抽象类不能实例化,但是可以按照多态的方式,由具体的子类实例化,也成为多态的一种,抽象类多态
抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法
抽象类的成员特点:成员变量:既可以是变量,也可以是常量,abstract不能修饰成员变量
构造方法:有,用于子类访问父类数据的初始化
成员方法:既可以是抽象的,也可以是非抽象的
抽象方法:强制要求子类做的事情
非抽象方法:子类继承的事情
一个抽象类如果没有抽象方法,目的是不让其他类创建本类对象,交给子类完成
接口:对外提供规则的都是接口
接口关键字用interface表示
interface 接口名{}
类实现接口用implements表示
class 类名 implements 接口名{}
接口不能实例化,只能按照多态的方式来实例化
接口的子类可以是抽象类,但是意义不大
可以是具体类,要重写接口中的所有抽象方法,一般都采用这种方式
接口成员特点:只能是常量,并且是静态的并公共的
默认修饰符:public static final
一般建议自己手动给出
接口没有构造方法
成员方法:只能是抽象方法,不能定义非抽象方法
默认修饰符:public abstract
一般也只是手动给出
类与接口是实现关系,并且还可以在继承一个类的同时实现多个接口
接口与接口是继承关系,可以单继承,也可以是多继承
package pra_03;
public class j_09 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat c=new Cat();
c.eat(); //Cat eat
Ani a=new Cat(); //父类引用指向子类对象
a.eat(); //Cat eat
Fa f=new So(); //父类引用指向子类对象
System.out.println(f.num); //10
Fa f1=new So();
f1.print(); //So
Pe p=new Sup();
System.out.println(p.name);
p.a(); //bbb
//向上转型,向下转型,父类引用指向子类对象就是向上转型
Sup sp=(Sup)p; //向下转型,一定先有向上转型才有向下转型
sp.fly();
//多态好处的体现
method2(new Cat2());
method2(new Dog());
//Aaa aaa=new Aaa(); 抽象类不允许被实例化
Aaa aaa=new Bbb();
aaa.eat();
//Inter inter=new Inter(); 接口不能被实例化,因为调用抽象方法没有意义
Inter i=new Ex(); //父类引用指向之类对象
i.printA();
Ex2 ex=new Ex2();
ex.printA(); //10
Ex3 ex2=new Ex3();
ex2.printA();
ex2.printB();
}
//如果把Dog强转成Cat,就会出现转换异常 ClassCastException
public static void method2(Animal a){ //当作参数的时候,用多态最好,因为扩展性强
//关键字,instanceof判断前边的引用是否是后面的数据类型
if(a instanceof Cat2){
Cat2 c=(Cat2)a;
c.eat();
c.catcatch();
}else if(a instanceof Dog){
Dog d=(Dog)a;
d.eat();
d.look();
}else{
a.eat();
}
}
}
class Ani{
public void eat(){
System.out.println("ani eat");
}
}
class Cat extends Ani{
public void eat(){
System.out.println("Cat eat");
}
}
class Fa{
int num=10;
public void print(){
System.out.println("Fa");
}
}
class So extends Fa{
int num=20;
public void print(){
System.out.println("So");
}
}
class Pe{
String name="Jo";
public void a(){
System.out.println("aaa");
}
}
class Sup extends Pe{
String name="sup";
public void a(){
System.out.println("bbb");
}
public void fly(){
System.out.println("ccc");
}
}
class Animal{
public void eat(){
System.out.println("eat");
}
}
class Cat2 extends Animal{
public void eat(){
System.out.println("cat2 eat");
}
public void catcatch(){
System.out.println("catch");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("Dog eat");
}
public void look(){
System.out.println("Dog look");
}
}
abstract class Aaa{ //抽象类
public abstract void eat(); //抽象方法
}
class Bbb extends Aaa{
public void eat(){
System.out.println("Aaa eat");
}
}
abstract class Ccc {
int num=10;
final int num2=20;
public Ccc(){}
public void print(){
System.out.println("111");
}
public abstract void method(); //子类必须对其重写才能使用
}
class Ddd extends Ccc{
public void method(){
System.out.println("222");
}
}
interface Inter{ //接口中的方法都是抽象的
int num=10; //实际上是final num=10;为常量,不得改变其值
public abstract void printA();
}
interface Inter2{ //接口中的方法都是抽象的
int num2=10; //实际上是final num=10;为常量,不得改变其值
public abstract void printB();
}
class Ex implements Inter{
public void printA(){
System.out.println("interface");
}
}
class Ex2 implements Inter{
public void printA(){
System.out.println(num);
}
}
class Ex3 implements Inter,Inter2{
public void printA(){
System.out.println("interfaceA");
}
public void printB(){
System.out.println("interfaceB");
}
}