Java 抽象类、接口、多态性

父类变量引用子类对象

  • 我们知道C++中用父类的指针和引用指向子类对象,从而实现多态,但是Java中没有指针,引用也和C++不同。
  • Java中的父类变量引用子类对象格式:Base b = new Derived(参数表)
    例如:Shape C1 = new Circle(5);

抽象类和抽象函数

  • 抽象类的定义方法是在class前加关键字abstract,抽象函数是在返回值前加关键字abstract。
  • Java的抽象类规则和C++一样,主要有:
    • 抽象类不存在对象
    • 有抽象函数的类就是抽象类(所以类名和函数名前都要加abstract)但是抽象类不一定要有抽象函数。
    • 继承抽象类的子类,如果想成为非抽象类,必须覆盖所有抽象函数。
abstract class Beverage {

	public final void prepareRecipe() {
		boilWater();
		brew();
		pourInCup();
		System.out.println(type()+"已经准备好了,请享用!");
	}  //整合每个步骤的虚函数
	
	public void boilWater() { System.out.println("热水已经烧好了!"); }
	public abstract void brew();
	public void pourInCup() {
		System.out.println(type() + "已经倒到杯子里了!");
	}
	public abstract String type();
}

class Tea extends Beverage {
	public void brew() { System.out.println("将茶叶放到热水里");}
	public String type() { return "茶"; }
}
class Coffee extends Beverage {
	public void brew() { System.out.println("将咖啡放到热水里"); }
	public String type() { return "咖啡"; }
}

public class Main {
	public static void main(String[] args) {
		 Beverage b = new Coffee();
		 b.prepareRecipe();
		 b = new Tea();
		 b.prepareRecipe();
	}
}

由这个例子,我们可以看出:当一个任务需要很多步骤完成,每个步骤有着不同的子类时,我们可以分别定义虚函数,再将虚函数整合到一个函数中。

接口

接口的概念

  • Java中的接口类似于C++中的纯虚类,来描述某个类所支持的操作,这些操作只有方法声明,没有具体实现,所有方法均为抽象方法。
  • 方法的具体实现在实现这个接口的类中完成。

接口的定义

  • 定义格式:
    修饰符 \quad 接口名 \quad extends \quad 接口名 \quad {
    \quad public static final \quad 数据类型 \quad 常量名 = 常量数据;
    \quad publlic abstract \quad 方法类型 \quad 方法名( [参数] )
    }
  • public是接口唯一访问控制修饰符,如果没有使用任何访问修饰符,表示只有与该接口在同一个包中的类或接口才可以访问这个接口。
  • 接口支持多重继承
  • 接口中定义常量和方法前的修饰语唯一,因此可以省略关键字。
  • 接口中定义的常量可以在使用接口的类中使用。如果类中重新定义同名变量则覆盖接口变量,想要引用接口变量,需要用 接口名.变量名

接口实现

  • 格式:
    修饰符 class 类名 implements 接口名1,接口名2, …
  • 非抽象类在实现接口时,在类中必须对接口中的所有方法给出具体体现
  • 在接口中声明方法时,可以省略public和abstract关键字,类在实现接口时,一定要有public来修饰。
  • 接口也是一种引用类型,用接口实现多态的方法是:声明接口类型的指针指向拥有接口的类。
interface Shape {
	double pi = 3.14;
	void setColor(String str);
}
interface Shape2D extends Shape {
	double area();
}
class Circle implements Shape2D {
	double radius;
	double pi = 1;  //覆盖Shape2D中的pi
	String color;
	public Circle(double r) { radius = r; }
	public double area() { return (Shape2D.pi*radius*radius); }  //使用Shape2D中的pi
	public void setColor(String str) { color = str; System.out.println("color="+color);}
}

public class Main {
	public static void main(String[] args) {
		Shape2D circle = new Circle(5);
		circle.setColor("blue");
		System.out.println("Area="+circle.area());
	}
}

在这里插入图片描述

多态

  • 在Java中,我们有和C++中相同的多态方法:即用父类指针指向子类对象。
  • Java中有一个特殊的接口类。需要特别说明的是与接口有关的多态性。之前已经提到可以用接口引用指向类,其实接口可以看成特殊的类,我们可以在类中定义一个接口成员,指向使用接口的类。
interface PCI {
	String show();
	void operate();
}
class NetWorkCard implements PCI {
	public String show() { return "网卡"; }
	public void operate() { System.out.println("我在传输网络数据"); }
}
class SoundCard implements PCI {
	public String show() { return "声卡"; }
	public void operate() { System.out.println("我在播放声音"); }
}
class MotherBoard {
	PCI pci;
	MotherBoard() { System.out.println("我是主板"); }
	void plugin(PCI in) { pci = in; System.out.println(in.show()+"插入到PCI插槽中"); }
	void operate() { pci.operate(); }
}

public class Main {
	public static void main(String[] args) {
		MotherBoard m = new MotherBoard();
		m.plugin(new NetWorkCard());
		m.operate();
		m.plugin(new SoundCard());
		m.operate();
	}
}

在这里插入图片描述

instanceof

用法:a instanceof A

a为某对象名,A为类名或接口名,返回boolean,当a是类A的对象,或a是类A子类的对象,或a所属的类包含接口A时,返回true。

getClass( )

getClass( )是Object类的方法,当要判断a是否就是类A的对象时,要用:
a.getClass( ) == A.class;

interface Print {
	void print();
}
class Base implements Print{
	int x;
	public Base(int xx) { x = xx; }
	public void print() { System.out.println(x); }
}
class Derived extends Base {
	public Derived(int x) { super(x); }
}

public class Main {
	public static void main(String[] args)  {
	    Derived D = new Derived(5);
		System.out.println(D instanceof Base);
		System.out.println(D instanceof Derived);
		System.out.println(D instanceof Print);
		System.out.println(D.getClass() == Derived.class);
		// System.out.println(D.getClass() == Base.class); 会报错
		Base B = new Derived(5);
		System.out.println(B.getClass() == Derived.class);
		System.out.println(B.getClass() == Base.class);
	}
}

除最后一个为false以外,其他均为true

猜你喜欢

转载自blog.csdn.net/qq_43575267/article/details/87402173
今日推荐