抽象类的使用限制

抽象类的使用限制

抽象类的组成和普通类的区别不大,但是由于有一点点使用以及定义的区别,所以会有以下概念会被忽略
1.抽象类里面由于会存在一些属性,在抽象类中一定会存在抽象方法,目的为属性初始化,并且子类对象初始化时依然满足于,先执行父类构造,再执行子类构造的情况
2.抽象类不能使用final定义:因为抽象类必须有子类,而final定义的类不能有子类
3.外部的抽象类不允许使用static声明,而内部的抽象类允许使用static声明,使用static声明的内部抽象类就相当于一个外部抽象类,继承的时候使用"外部类.内部类"的形式表示类名称

确定抽象类中存在构造方法

4.任何情况下,如果要执行类中的`static`方法的时候,都可以在没有对象的时候直接调用,对于抽象类也是一样
5.有些时候,由于抽象类只需要一个特定的系统子类操作,所以可以忽略掉外部子类
abstract class A{ // 定义一个抽象类
	public A(){
		System.out.println("************");
	}
	public void print(){ // 普通方法
		System.out.println("存在普通方法");
	}
	// 此方法并没有方法体的声明,并且存在有abstract关键字,表示抽象方法
	public abstract void func();
}

// 一个子类只能够继承一个抽象类,属于单继承局限
class B extends A{ // B类是抽象类的子类并且是一个普通类
	public B(){
		System.out.println("#####################");
	}
	public void func(){
		System.out.println("Hello world");
	}

}

public class testDemo{
	public static void main(String args[]){
		A a = new B(); // 向上转型
		a.func();
	}
}

执行结果

root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
root@079a25844567:/opt/lixinghua/OOP# java testDemo     
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
************
#####################
Hello world

使用内部类的static声明

abstract class A{ // 定义一个抽象类
	// static定义的内部类属于外部类
	static abstract class B{
		public abstract void print();
	}
}
class X extends A.B {
	public void print(){
	System.out.println("****************");
	}
}

public class testDemo{
	public static void main(String args[]){
		A.B ab = new X();// 向上转型
		ab.print();
	}
}

输出结果

root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
root@079a25844567:/opt/lixinghua/OOP# java testDemo     
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
****************

抽象类直接调用static方法

abstract class A{
	public static void print(){
		System.out.println("*************");
	}
}
public class testDemo{
	public static void main(String args[]){
		A.print();
	}
}

输出结果

root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
root@079a25844567:/opt/lixinghua/OOP# java testDemo     
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
*************

对外部隐藏内部子类实现

abstract class A{
	public abstract void print();
	private static class B extends A { // 内部抽象类的子类
		public void print(){ // 覆写抽象类的方法
			System.out.println("***********");	
		}
	}
	// 这个方法不受实例化对象的控制
	public static A getInstance(){
		return new B();
	}
}
public class testDemo{
	public static void main(String args[]){
		// 此时取得抽象类对象的时候完全不知道B类的存在
		A a = A.getInstance();
		a.print();
		A.getInstance().print();;
	}
}

执行结果

root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
root@079a25844567:/opt/lixinghua/OOP# java testDemo     
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
***********
***********

这样的设计在系统类库之中会比较常见,目的:为用户隐藏不需要知道的子类

分析代码

分析代码执行结果

abstract class A{
	public A(){ // 2.调用父类构造方法
		this.print(); // 3.调用print()方法
	}
	public abstract void print();
}

class B extends A{
	private int num = 100;
	public B(int num){
		this.num = num;
	}
	public void print(){ //4.调用覆写方法
        // 此时未对num属性初始化,其值为默认值
		System.out.println("num= " + num);
	}
}

public class testDemo{
	public static void main(String args[]){
		new B(30); // 1.执行构造
	}
}

执行结果

root@079a25844567:/opt/lixinghua/OOP# vim testDemo.java 
root@079a25844567:/opt/lixinghua/OOP# javac testDemo.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
root@079a25844567:/opt/lixinghua/OOP# java testDemo     
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
num= 0

解决思路:在任何一个类的构造执行完之前,所有属性的内容都是其对应数据类型的默认值,而子类对构造方法执行之前,一定先执行父类构造,那么此时子类构造由于没有执行,所以num就是0

原文地址:https://www.cnblogs.com/anyux/p/11940301.html