抽象类的用法以及定义

与具体类比较

  1. 1.抽象类不能直接实例化
  2. 2.抽象类可以不含抽象方法
  3. 3.抽象类中含有抽象方法时,如果子类继承该抽象类,则必须重写该抽象方法
  4. 4.抽象类可以有非抽象方法
  5. 5.允许(但不要求)抽象类包含抽象成员。
  6. 6.抽象类不能被密封。
  7. 7.抽象类含有非抽象方法,而且子类继承该类时,重写了该方法,那么该子类的对象调用该方法时,是子类中的方法;如果子类没有重写该父类中的非抽象方法,那么子类对象调用的是父类中的方法。

与接口比较

抽象类表示该类中可能已经有一些方法的具体定义,但是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。
接口是引用类型的,和抽象类的相似之处有三点:
  1. 不能实例化;
  2. 包含未实现的方法声明;
  3. 派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员)。 [2]  
抽象类与接口紧密相关。然而接口又比抽象类更抽象,这主要体现在它们的差别上:
  1. 类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决 多重继承问题的。
  2. 抽象类当中可以存在非抽象的方法,可接口不能,且它里面的方法只是一个声明必须用public来修饰没有具体实现的方法。
  3. 抽象类中的 成员变量可以被不同的 修饰符来修饰,可接口中的成员变量默认的都是静态 常量(static final)。
  4. 抽象类是对象的抽象,然而接口是一种行为规范。
抽象类可以不含抽象方法,抽象类中的抽象方法,子类必须实现。例1:
package com.test.abstractTest;


abstract class A{
void test1(){
System.out.println("test1");
}
abstract void test2();
}


public class TestAbstractClass extends A {


@Override
void test2() {
System.out.println("test2");
}


public static void main(String [] args){
TestAbstractClass test = new TestAbstractClass();
test.test1();
test.test2();
}
}

运行结果:test1   test2
抽象类含有非抽象方法,而且子类继承该类时,重写了该方法,那么该子类的对象调用该方法时,是子类中的方法;如果子类没有重写该父类中的非抽象方法,那么子类对象调用的是父类中的方法。例2:
package com.test.abstractTest;


/**
 *
 * @description:
 * @date 2016-7-15 下午2:41:43
 * @version 2.0
 */
class Test {
Shape s;


Test(Shape s) {
this.s = s;
}


//两倍是
public double getTwo(Shape h) {
double area = h.getArea();
return 2 * area;
}


public static void main(String[] args) {
System.out.print("测试开始");
Shape s1 = new Square(1);
System.out.println("正方形的面积" + s1.getArea());
System.out.println("正方形的周长" + s1.getPan());


Shape s2 = new Rectangle(1, 2);
System.out.println("长方形的面积" + s2.getArea());
System.out.println("长方形的周长" + s2.getPan());


Shape s3 = new Circle(1);
System.out.println("圆的面积" + s3.getArea());
System.out.println("圆的周长" + s3.getPan());


Test t = new Test(s1);
System.out.println("正方形面积的两倍" + t.getTwo(s1));


}
}


//模型
abstract class Shape {// 抽象类
public abstract double getArea();// 抽象方法


//public abstract double getPan();
public double getPan() {
return 0;
}
}


//正方形
class Square extends Shape {
protected double len;//长


Square(double len) {
this.len = len;
}


public double getArea() {
return len * len;
}


/*public double getPan() {
return 4 * len;
}*/
}


//长方形继承了正方形
class Rectangle extends Square {

private double wid;//宽


Rectangle(double len, double wid) {
super(len);
this.len = len;
this.wid = wid;
}


public double getArea() {
return wid * len;
}


public double getPan() {
return (wid + len) * 2;
}
}


//圆
class Circle extends Shape {
private double r;


Circle(double r) {
this.r = r;
}


public double getArea() {
return Math.PI * r * r;
}


public double getPan() {
return Math.PI * r * 2;
}
}
运行结果:
测试开始正方形的面积1.0
正方形的周长0.0
长方形的面积2.0
长方形的周长6.0
圆的面积3.141592653589793
圆的周长6.283185307179586
正方形面积的两倍2.0

喜欢的朋友可以扫描我的个人公众号,有好东西可以一起分享。免费获取各种学习视频、源码、PPT资料

也可以微信搜索公众号:Java程序员那些事


版权声明:本文为Lingfeng928原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。