zoukankan      html  css  js  c++  java
  • 抽象类的使用限制

    抽象类的使用限制

    抽象类的组成和普通类的区别不大,但是由于有一点点使用以及定义的区别,所以会有以下概念会被忽略
    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

  • 相关阅读:
    ES6/ES2015核心内容(上)
    集合转数组的toArray()和toArray(T[] a)方法
    重复输出一个给定的字符串
    10道典型的JavaScript面试题
    用 JavaScript 检测浏览器在线/离线状态(JavaScript API — navigator.onLine)
    List<实体>与List<String>数据互转
    CSS实现四种loading动画效果
    Windows上安装Mac OS
    Android应用层View绘制流程之measure,layout,draw三步曲
    推断输入信息是否为空
  • 原文地址:https://www.cnblogs.com/anyux/p/11940301.html
Copyright © 2011-2022 走看看