Java基础语法 abstract关键字全方位总结

abstract 修饰符,用来创建抽象类和抽象方法,也就是说abstract 修饰的类似抽象类,abstract 修饰的方法即抽象方法。

说到抽象,想必大家第一个联想到的就是抽象画,基本上看不懂画的是啥,只能说它在表达某个概念。在Java中我们使用abstract关键字来表达抽象。

学习abstract修饰的抽象之前,先举个例子:

我们说车子都可以跑(run)。但有几个轮子,怎么跑,对于不同的车有不同的结果。自行车需要人踩着跑,汽车发动机推动跑等等,那么我们可以车表达为抽象类。代码实现如下:

/**
 * 抽象类:abstract修饰车子类
 */
public abstract class Car {
    
    
    //抽象方法:abstract修饰run()方法
	public abstract void run();
}
/**
 * 自行车
 */
class Bicycle extends Car{
    
    
    //重写run()方法
	@Override
	public void run() {
    
    
		System.out.println("人踩着跑。。。");
	}
	
}
/***
 * 汽车
 */
class Automobile extends Car{
    
    
	//重写run()方法
	@Override
	public void run() {
    
    
		System.out.println("发动机驱动跑。。。");
	}
}

假如后面各种车,它们倒着跑、悬在空中跑,随它怎么跑,只需要继承抽象类实现自己的功能就行了。相信说到这里大家对抽象已有一个初步的印象了吧。

  • 抽象方法:

    1、从上面的例子中我们可以看到抽象方法跟普通方法是有区别的,它没有自己的方法主体(没有{ }包起来的业务逻辑),跟接口中的方法有点类似。所以我们没法直接调用抽象方法。

    2、抽象方法不能用private修饰,因为抽象方法必须被子类实现(覆写),而private权限对于子类来说是不能访问的,所以就会产生矛盾。

    3、抽象方法也不能用static修饰,试想一下,如果用static修饰了,那么我们可以直接通过类名调用,而抽象方法压根就没有主体,没有任何业务逻辑,这样就毫无意义了。

  • 抽象类:

    1、用abstract关键字来表达的类,其表达形式为:(public)abstract class 类名{ }。

    2、抽象类不能被实例化,也就是说我们没法直接new 一个抽象类。抽象类本身就代表了一个类型,无法确定为一个具体的对象,所以不能实例化就合乎情理了,只能用它的继承类实例化。

    3、抽象类虽然不能被实例化,但有自己的构造方法(这个后面再讨论)。

    4、抽象类与接口(interface)有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类中可以有实例方法,并实现业务逻辑,比如我们可以在抽象类中创建和销毁一个线程池。

    5、抽象类不能使用final关键字修饰,因为final修饰的类无法被继承,而对于抽象类来说就是需要通过继承去实现抽象方法,这又会产生矛盾。

  • 抽象类与抽象方法的关联:

    1、如果一个类中至少有一个抽象方法,那么这个类一定是抽象类,但反之则不然。也就是说一个抽象类中可以没有抽象方法。这样做的目的是为了此类不能被实例化。

    2、如果一个类继承了一个抽象类,那么它必须全部覆写抽象类中的抽象方法,当然也可以不全部覆写,如果不覆写全部抽象方法则这个子类也必须是抽象类(这样做就无意义了)

    public abstract class Car {
          
          
    	public void mothod1(){
          
          
            
    	}
    public abstract void mothod2();
    
    public abstract void method3();
    }
    
    class Bicycle extends Car{
          
          
    	@Override
    	public void mothod2() {
          
          //需要覆写抽象方法mothod2
    	
    	}
    	@Override
    	public void method3() {
          
          //需要覆写抽象方法mothod3
    	
    	}
    }
    
  • 抽象类的构造器:

    先来看一个例子:

    public abstract class Car {
          
          
    	Car(){
          
          
    		System.out.println("抽象方法无参构造函数");
    	}
        
    	Car(String a){
          
          
    		System.out.println("抽象有参构造方法");
    	}
        
    	public void mothod1(){
          
          
    		System.out.println(this.getClass());
    		System.out.println("抽象类的实例方法");
    	}
    
    	public abstract void mothod2();
    }
    
    /**
     * 自行车
    */
    class Bicycle extends Car{
          
          
    	Bicycle(){
          
          
       		System.out.println("子类无参构造函数");
       }
    
       @Override
       public void mothod2() {
          
          //需要覆写抽象方法mothod2
       	
       }
    }
       
    /**另一个包的测试类**/
    public class Test {
          
          
    	public static void main(String[] args) {
          
          
       		Bicycle b = new Bicycle();
            b.mothod1();
        }
    }
    
    运行结果:
    抽象方法无参构造函数
    子类无参构造函数
    class com.wedu.Bicycle
    抽象类的实例方法
    

    从上面的例子中可以看出:

    1、抽象类是有构造方法的(当然如果我们不写,编译器会自动默认一个无参构造方法)。而且从结果来看,和普通的继承类一样,在new 一个子类对象时会优先调用父类(这里指的是抽象类Car)的构造器初始化,然后再调用子类的构造器。至此相信大家都会有这样一个疑问,为什么抽象方法不能实例化却有构造器呢? 对于这个问题网上也中说纷纭,没有确定答案。

    我是这样想的:既然它也属于继承的范畴,那么当子类创建对象时必然要优先初始化父类的属性变量和实例方法,不然子类怎么继承和调用呢?而它本身不能实例化,因为它本身就是不确定的一个对象,如果它能被实例化,那么我们通过它的对象来调用它本身的抽象方法是不是有问题。所以不能实例化有在情理之中。如果实在理解不了就记住这个规定就行。

    2、对于抽象类中的非statci(静态)和非abstract(抽象)方法中的this关键字(静态方法中不能有关键字this之前已经讨论过,可参考Java基础语法 static关键字全方位总结)代表的是它的继承类,而非抽象类本身,这个好理解,因为抽象类本身不能被实例化。如果有多个继承类,谁调用this就代表谁。

抽象类有什么好处呢?
1、由于抽象类不能被实例化,最大的好处就是通过方法的覆盖来实现多态的属性。
2、抽象类将事物的共性的东西提取出来,由子类继承去实现,代码易扩展、易维护。

猜你喜欢

转载自blog.csdn.net/liulei952413829/article/details/114658714