如何调用抽象类中的抽象方法?以及如何调用接口中的抽象方法?

目录

  • 1. 如何调用抽象类中的抽象方法?
  • 2. 如何调用接口中的抽象方法?

1. 如何调用抽象类中的抽象方法?

抽象类就是不能使用new方法进行实例化的类,即没有具体实例对象的类。抽象类有点类似“模板”的作用,目的是根据其格式来创建和修改新的类。对象不能由抽象类直接创建,只可以通过抽象类派生出新的子类,再由其子类来创建对象。当一个类被声明为抽象类时,要在这个类前面加上修饰符abstract.

在抽象类中的成员方法可以包括一般方法和抽象方法。抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。当一个方法为抽象方法时,意味着这个方法必须被子类的方法所重写,否则其子类的该方法仍然是abstract的,而这个子类也必须是抽象的,即声明为abstract.

抽象类中不一定包含抽象方法,但是包含抽象方法的类一定要被声明为抽象类。抽象类本身不具备实际的功能,只能用于派生其子类。抽象类中可以包含构造方法,但是构造方法不能被声明为抽象。

调用抽象类中的方法(抽象方法和非抽象方法),如果方法是static的,直接 抽象类。方法 就可以了;如果是非static的则必须需要一个继承的非抽象类,然后用这个非抽象类的实例来调用方法。

抽象类可以实现接口,接口中的方法 在抽象类中可以不实现,当有子类继承 抽象类时,并且子类不是抽象类时,子类需要将抽象类中的 抽象方法和接口中的方法都实现

抽象类不能用final来修饰,即一个类不能既是最终类又是抽象类。

总结: abstract不能与private、static、final、native并列修饰同一个方法。

注意:子类继承父类方法后,这个子类对象如果执行方法的话,只要子类重写了就执行子类的,不执行父类的。

package xxx.java;

public class AbstractTest {
	public static void main(String[] args) {
		
		//一旦Person类抽象了,就不可实例化(不能造对象了)
//		Person p1 = new Person();
//		p1.eat();
	}
}
abstract class Creature{
	public abstract void breath();
}

abstract class Person extends Creature{
	String name;
	int age;
	
	public Person(){
		
	}
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	//不是抽象方法:有空的方法体
//	public void eat(){
//	
//	}
	//抽象方法
	public abstract void eat();
	
	public void walk(){
		System.out.println("人走路");
	}
}

class Student extends Person{
	
	public Student(String name,int age){//父类Person中有构造器,所以子类可以使用父类中的构造器
		super(name,age);
	}
	public Student(){
	}
	
	//Student类不能调用父类中的eat方法(抽象方法),要使用eat方法要么额外在子类中把父类Person中的eat方法重写,要么把Student类也弄成抽象类(abstract class Student extends Person)
	//即:若子类重写了父类中的所有的抽象方法后,此子类方可实例化;若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
	public void eat(){
		System.out.println("学生多吃有营养的食物");
	}

	@Override
	public void breath() {//Student类继承Person类,Person类继承Creature类,Creature类用抽象类修饰了,故Student类要调用Creature类中的breath功能,则要么重写breath方法,要么Student类也抽象化
		System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
	}
}

在Person类中,抽象方法eat要省略方法体:

public abstract void eat();

我们不能直接通过造Person类的对象调用该eat方法(抽象类不能实例化,无法造抽象类的对象去调用该类中的方法),要调用eat方法,只能造Person类的子类(如Student类),在Student类(不再是抽象类)中重写父类中的所有抽象方法(重写之后的eat方法也不再是抽象方法)

注:若子类重写了父类中的所有的抽象方法后,此子类方可实例化;若子类没有重写父类中的所有的抽象方法则此子类也是一个抽象类,需要使用abstract修饰。即:

class Student extends Person{
	
	public Student(String name,int age){//父类Person中有构造器,所以子类可以使用父类中的构造器
		super(name,age);
	}
	public Student(){
	}
	public void eat(){
		System.out.println("学生多吃有营养的食物");
	}

	@Override
	public void breath() {//Student类继承Person类,Person类继承Creature类,Creature类用抽象类修饰了,故Student类要调用Creature类中的breath功能,则要么重写breath方法,要么Student类也抽象化
		System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
	}
}

改为:

abstract class Student extends Person{
	
	public Student(String name,int age){//父类Person中有构造器,所以子类可以使用父类中的构造器
		super(name,age);
	}
	public Student(){
	}
	public void eat(){
		System.out.println("学生多吃有营养的食物");
	}

	@Override
	public void breath() {//Student类继承Person类,Person类继承Creature类,Creature类用抽象类修饰了,故Student类要调用Creature类中的breath功能,则要么重写breath方法,要么Student类也抽象化
		System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
	}
}

但如果Student类又变成抽象类,则Student类又不能能通过造Student类的对象去调用Student类中的方法了。即如果不在Student类中重写父类Person中的全部方法,单纯在Student类前加abstract只能保证程序不出错而已。(本人不成熟的见解,有误望指出)

所以,一般来说,要想调用抽象类中的抽象方法,应该造该抽象类(父类)的子类,然后在子类中重写父类的全部方法,然后就可以通过造子类的对象去调用子类中重写过的方法。

2. 如何调用接口中的抽象方法?

JDK7及以前,接口中的方法一定是抽象方法(那么方法前缀没有abstract,也默认有)。

**接口中不能定义构造器的!**意味着接口不可以实例化(不能通过直接new对象去调用接口中的方法)。要用接口,得通过类去实现(implements)的方式来使用。(即把接口转换成类去使用):

package xxx.java1;

public class InterfaceTest {
	public static void main(String[] args) {
		System.out.println(Flyable.MAX_SPEED);
		System.out.println(Flyable.MIN_SPEED);
//		Flyable.MIN_SPEED = 2;//就算48行省略了public static final,Flyable.MIN_SPEED依然不能赋值
		
		Plane plane = new Plane();//75行开始重写了fly和stop方法,故可以new对象去调用Plane类中的属性方法了。
		plane.fly();//通过传入该接口的实现类Plane的对象plane来调用接口Flyable中的方法
	}
}


interface Flyable{
	
	//全局常量
	public static final int MAX_SPEED = 7900;//第一宇宙速度
	int MIN_SPEED = 1;//可以省略了public static final
	
	//抽象方法
	public abstract void fly();
	//方法中可以省略了public abstract
	void stop();
	
	
	//Interfaces cannot have constructors接口中不能定义构造器的!意味着接口不可以实例化
//	public Flyable(){
//		
//	}
}

class Plane implements Flyable{

	//使用接口中的这两个方法时,由于接口中的方法是抽象方法,故在Plane类中要么重新实现一下这两个方法,要么将Plane类抽象化(class前面加abstract)
	
	//下面重新实现一下这两个方法:
	//如果实现类覆盖了接口中的所有抽象方(fly,stop)法,则此实现类就可以实例化
    //如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
	@Override
	public void fly() {
		System.out.println("通过引擎起飞");
	}

	@Override
	public void stop() {
		System.out.println("驾驶员减速停止");
	}
	
}

其中,Flyable接口中的方法是抽象方法,和上面讲的调用抽象方法的手法一样,我们需要在实现类Plane中重写Flyable接口中的所有方法,然后再造实现类Plane的对象plane去调用Flyable接口中的相应的方法(如fly)。

如果只是在class Plane implements Flyableqian前面加上abstract,虽然可避免报错,但还是无法调用Flyable接口中的方法(抽象类无法实例化)。

你可能感兴趣的:(java,java)