今天,准备看看公司项目是如何封装基本的一些基础的方法。比如:BaseConttoller/BaseService/BaseEntity extends AbstractEntity 等
突然发现,原来这些基础的类都是抽象类(用 abstract 修饰的),原来认为抽象类都是只可以实现抽象方法的;
现在看来,抽象类也可以拥有具体实现了的方法,只是不能直接实例化(不能直接new 抽象方法);
以举例的方式说到如何区分抽象类和接口,这里我们从Java语法谈起,使我们更加了解这两者的内在区别。它们的语法区别:
1)接口不能有构造方法,抽象类可以有。
2)接口不能有方法体,抽象类可以有。
3)接口不能有静态方法,抽象类可以有。
4)在接口中凡是变量必须是public static final,而在抽象类中没有要求。
忽然有此一文,是因为同学疑惑道:抽象类居然还有构造方法,又不能直接用来new。我的解释是平时在抽象类中对于构造方法的存在,没有什么印象,是因为IDE默认为你生成了一个无参构造方法,也可以显式地写出构造方法,这个构造方法,是用来被子类调用的,因为任何子类都必须调用从Object开始的所有父亲的构造方法,才算完成初始化工作。那么我引申一下,问他们,接口有构造方法吗?他们的理解,抽象可以有,为什么接口不可以有?!那么在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。这又何解?
从语法的角度来说,抽象类必须有构造方法,而接口严禁有构造方法,这本身也说明了它们性质的不同。抽象类是一个类,别的类是用关键字 extends 来继承下来,并扩展的,有非常强的is-a的关系,这种关系一般来说符合里氏代换原则。而接口,是被其他类用关键字 implements 来实现接口定义的方法的。如果没什么区别,何必整出两个不同的关键字。 接口只是定义功能和行为规范,如果一个类实现了一个接口,那么这个类必须遵守这个接口的方法约定,但没有is-a的关系。把墙壁上的“小学生行为规范”想象成一个接口,那么是小学生必须遵守这个约定,但小学生不是“行为规范”。
构造方法是用来在对象初始化前对对象进行一些预处理的,提供了实例化一个具体东西的入口。接口只是声明而已,不一定要进行什么初始化,就算要进行初始化,也可以到实现接口的那一些类里面去初始化。接口只是用来表述动作,表述规范来的,可以new一台computer,但我们无法new一个IDE、SATA、PCI、PS-2。因此,接口要构造方法何用?接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器的调用次序,构造器是属于类自己的,不能继承,因为是纯虚的,接口不需要构造方法。而抽象类是具体类的祖先,即使是石器时代,也总要干些初始化的工作,抽象类虽然是不能直接实例化,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都,都会调用父类的构造方法,初始化一个类,先初始化父类,有没有说初始化接口。
1)Java中抽象类和接口中有构造方法吗?
在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。
A. 构造方法用于初始化成员变量,但是接口成员变量是常量,无需修改。接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,
B. 类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器链的调用次序
C. 构造器是属于类自己的,不能继承。因为是纯虚的,接口不需要构造器。
在抽象类中可以有构造方法,只是不能直接创建抽象类的实例对象,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都会调用父类的构造方法,初始化一个类,先初始化父类。
A.方法名与类名相同;
B.没有返回类型(例如return、void等);
C.不能被static、final、native、abstract和synchronized修饰,不能被子类继承。
D.父类的构造方法不能被子类调用,可以通过super语句调用父类的构造方法。
E.构造方法可以重载,以参数的个数,类型,顺序,分为空参构造方法和有参构造方法。
注:
抽象类中不一定有抽象方法,抽象方法一定存在于抽象类中。
继承抽象类的可以是普通类,但必须重写抽象类中的所有抽象方法,也可以是抽象类,无需重写抽象类中的所有抽象方法。
注:
可以说是一种特殊的抽象类,里面的方法全是抽象方法。
子类实现接口必须对接口中的方法全部重写。
1)接口不能有构造方法,抽象类可以有。
2)接口不能有方法体,抽象类可以有。
3)接口不能有静态方法,抽象类可以有。
4)在接口中凡是变量必须是public static final,而在抽象类中没有要求。
直接给答案:可以
无论是无参构造方法,还是有参构造方法都可以正常存在
之所以产生这个疑问,是因为Java抽象类本身的要求抽象类是不能被实例化的,抽象类只能作为其他类的父类,或者通过向上转型指向其子类。所以既然抽象类是不允许被实例化的,那么他的构造方法存在是否还有实际意义?
直接上例子
//抽象父类
abstract public class Shape {
public Shape(){
System.out.println("这是Shape的构造方法");
}
public Shape(String test){
System.out.println(test);
}
abstract public double area();
}
//子类
public class Circle extends Shape {
public final double PI=3.14;
private double r; //半径
public Circle() {
}
public Circle(double r) {
super("测试");
this.setR(r);
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
@Override
public double area() {
return PI*this.getR()*this.getR();
}
}
//子类
public class Rectangle extends Shape {
private double length;
private double width;
public Rectangle() {
}
public Rectangle(double length, double width) {
this.setLength(length);
this.setWidth(width);
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double area() {
return this.getLength()*this.getWidth();
}
}
//测试类
public class TestShape {
public static void main(String[] args) {
Shape shape1 =new Circle(3);
Shape shape2=new Rectangle(3,4);
System.out.println("圆的面积为:"+shape1.area());
System.out.println("矩形的面积为:"+shape2.area());
}
}
这里是程序的输出结果
显然,抽象父类的构造方法都被执行到了
简单解释下原因,在实例化子类对象的时候,无论子类的父类是不是抽象类都会先调用父类的构造方法,如果你在实例化子类对象的地方打上断点逐步执行,你会发现在执行子类构造方法之前会先进到父类中执行父类的构造方法,初始化一个子类会先初始化父类。
所以父类的构造方法是会被执行到的,可以在其中完成一些你的业务逻辑
今天,准备看看公司项目是如何封装基本的一些基础的方法。比如:BaseConttoller/BaseService/BaseEntity extends AbstractEntity 等
突然发现,原来这些基础的类都是抽象类(用 abstract 修饰的),原来认为抽象类都是只可以实现抽象方法的;
现在看来,抽象类也可以拥有具体实现了的方法,只是不能直接实例化(不能直接new 抽象方法);
转载于:https://my.oschina.net/craftsdream/blog/518074
接口可以继承接口。
抽象类并不能继承接口,但可以实现接口。
抽象类可以继承具体类,前提是具体类必须具有构造函数且具有访问权限。这里需要说明,当一个具体类没有写构造函数时,系统会自动生成默认的无参构造器,意味着没有写构造函数的具体类也可以被抽象类继承。但是,一旦将具体类的无参构造器设置访问修饰符为 private 时,抽象类则不可以继承。
抽象类可以有静态的 main 方法。抽象类在面向对象中是被用来描述现实中的抽象事物, 抽象类没有对象概念所以不能被实例化. 但可以定义属性和方法, 其中属性方法都可以是静态的. 静态的意义其实就是在栈内存中只有一个, 所以该成员也会先于对象出现在内存中, 所以静态并没有违反抽象的原则. 抽象类中可以定义静态成员.
interface IA{}
interface IB{}
interface I extends IA,IB{}//接口可以继承多个接口
abstract class E implements IA{} //抽象类可以实现接口,但不可以继承接口
abstract class F extends C{}//抽象类可以继承具体类
class D{private D(){}}
//abstract class G extends D{}//Implicit super constructor D() is not visible for default constructor. Must define an explicit constructor抽象类不可以继承无权限构造器的具体类
abstract class H{public static void main() {}}//抽象类可以有静态的main方法