zoukankan      html  css  js  c++  java
  • 抽象类(一):

    为何会出现抽象类这种类?

    1、某些情况下,父类只知道子类需要哪些方法,但是不知道子类如何实现这些方法,或者每个子类对同一方法的实现都不同

    2、所以允许父类定义方法时,只定义方法,但是不具体实现,定义的这种方法称为抽象方法,包含这种抽象方法的类,就被称为抽象类

    3、抽象方法:只有方法签名,没有方法实现的方法,抽象方法用 abstract 修饰 ,如:

    public abstract double getHeight();
    

     4、上面的代码定义了一个 抽象方法:getHeight();只有方法签名,没有后面的方法体。

    因此总结出抽象方法和抽象类的一些规则如下:

    1、抽象类和抽象方法必须用 abstract 修饰符来修饰

    2、抽象方法不能有方法体

    3、抽象类不能被实例化,无法使用 new 关键字来调用抽象类的构造器来实现实例对象,即使抽象类里不包含抽象方法,这个类也不能被实例化

    4、抽象类可以包含成员变量、方法(普通方法、抽象方法都可以)、构造器,初始化块,内部类(接口、枚举)5种成分

    5、抽象类的构造器不能用于创建实例,只能用于被其子类调用

    6、包含抽象方法的类,只能被定义为抽象类

    7、抽象类里可以没有抽象方法

    8、类包含抽象方法是指:

      .8.1、直接定义了一个抽象方法

      .8.2、继承了一个抽象父类,但没有完全实现父类的抽象方法

      .8.3、实现了一个接口,但没有完全实现接口包含的抽象方法

    9、归纳起来,抽象类可以用 “有得有失” 四个字来形容:

      有得:抽象类多了一个能力,能包含抽象方法

      有失:抽象类失去了一个能力,不能用于创建实例

    10、使用 abstract 修饰的类必须被继承,使用 abstract 修饰的方法必须被重写

       使用 final 修饰的类不能被继承,使用 final 修饰的方法不能被重写

      所以 abstract 和 final 永远不能一起用

    如下代码定义了一个抽象类,并被不同的子类继承实现:

    import static java.lang.System.*;
    //-定义一个抽象类,作为父类
    abstract class Shape{
    	
    	{
    		out.println("执行Shape类的普通初始化块!");
    	}
    
    	private String color;
    	
    	//-定义两个抽象方法,让子类去重写实现
    	public abstract double getPerimeter();
    
    	public abstract String getType();
    
    	public Shape(){
    		
    	}
    
    	public Shape(String color){
    		out.println("执行带参数的Shape类构造器!");
    		this.color=color;
    	}
    	
    	public String getColor(){
    		return this.color;
    	}
       
    	public void setColor(String color){
    		this.color=color;
    	}
    }
    
    //-子类 继承抽象父类
    class Triangle extends Shape{
    	private double a;
    	private double b;
    	private double c;
    	
    	public Triangle(String color,double a,double b,double c){
    		//-super关键字 调用父类构造器
    		super(color);
    		setSides(a,b,c);
    	}
    	
    	public void setSides(double a,double b,double c){
    		if(a>=b+c||b>=a+c||c>=a+b){
    			out.println("三角形的两边之和必须大于第三边!");
    			return;
    		}
    		this.a=a;
    		this.b=b;
    		this.c=c;
    	}
    
    	//-重写实现父类 getPerimeter() 方法
    	public double getPerimeter(){
    		return a+b+c;
    	}
    	
    	//-重写实现父类 getType() 方法
    	public String getType(){
    		return "三角形";
    	}
    	
    	
    }
    
    //-子类 继承抽象父类
    public class Circle extends Shape{
    	private double radius;
    
    	public Circle(String color,double radius){
    		//-super关键字 调用父类构造器
    		super(color);
    		this.radius=radius;
    	}	
    
    	//-重写实现父类 getPerimeter() 方法
    	public double getPerimeter(){
    		return 2*Math.PI*radius;
    	}
    	
    	//-重写实现父类 getType() 方法
    	public String getType(){
    		return "圆形";
    	}
    
    	public void setRadius(double radius){
    		this.radius=radius;
    	}
    	
    	public double getRadius(){
    		return this.radius;
    	}
    	
    	public static void main(String[] args){
    	
    		//-分别调用两个子类中重写的 方法:
    		Shape s1=new Triangle("红色",3,4,5);
    		out.println("周长是:"+s1.getPerimeter());
    		out.println("图形是:"+s1.getType());
    		out.println();
    		
    		Shape s2=new Circle("蓝色",5);
    		out.println("周长是:"+s2.getPerimeter());
    		out.println("图形是:"+s2.getType());
    		out.println();
    	
    		//-改变一下写法:
    		Triangle s3=new Triangle("红色",3,4,5);
    		out.println("周长是:"+s3.getPerimeter());
    		out.println("图形是:"+s3.getType());
    		out.println();
    		
    		Circle s4=new Circle("蓝色",5);
    		out.println("周长是:"+s4.getPerimeter());
    		out.println("图形是:"+s4.getType());
    	}
    }
    

     运行结果:

    如上代码看到:利用抽象类和抽象方法,可以更好的发挥多态的优势,使程序可以更灵活,但是不用抽象类抽象方法,结果是一样的。

    注:

    1、abstract 不能修饰成员变量,不能修饰局部变量,即:没有抽象成员变量、抽象局部变量的说法

    2、abstract 不能修饰构造器,也没有抽象构造器的说法,抽象类里定义的构造器只能是普通构造器

    3、当使用 static 修饰方法时,表示这个方法属于类本身,即通过类就能调用该方法,但如果该方法被定义为抽象方法,当用该类来调用该方法时,就会出现错误,即调用了一个没有方法体的方法,因此: static 和 abstract 不能同时修饰一个方法,即没有所谓的类抽象方法

    4、static 和 abstract 并不是绝对互斥的,他们可以同时修饰内部类

    5、abstract 修饰的方法只有被子类重写才有意义,因此 abstract 方法不能定义为 private 访问权限,即:abstract 和 private 不能同时修饰方法

  • 相关阅读:
    hdu 5071
    HDU4945 2048(dp)
    ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)
    HDU Destroy Transportation system(有上下界的可行流)
    Treap模板
    HDU4916 Count on the path(树dp??)
    HDU2829 Lawrence(斜率优化dp)
    HDU3507 Print Article(斜率优化dp)
    POJ3164 Command Network(最小树形图)
    Codeforces 452E Three Strings(后缀自动机)
  • 原文地址:https://www.cnblogs.com/baby-zhude/p/8119737.html
Copyright © 2011-2022 走看看