抽象类是程序设计中对问题分析后得出的抽象概念,抽象类只表示一种抽象的概念,是描述其子类所共有的属性和方法,抽象类不能被实例化为一个对象,必须由子类对其进行具体的实现。
抽象类和抽象方法的定义方式都是在类名和方法之前加上abstract关键字,其他定义与普通方法一致,也需要返回类型,方法名和参数列表,不同的是抽象方法没有方法体,并且抽象类可以包含非抽象方法的
定义抽象类:
abstract class Person{ //定义抽象类
public static final String home = "中国"; //定义一个国家常量
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void say(); //定义抽象方法,没有方法体
}
class Studnet extends Person{
@Override
public void say() { //重写抽象类中的所有抽象方法
System.out.println("我叫"+getName()+"是"+home+"人");
}
}
public class Demo {
public static void main(String[] args) {
Studnet s = new Studnet();
s.setName("BigYellow");
s.say();
}
}
我叫BigYellow是中国人
子类继承抽象类时,必须实现抽象类中所有的抽象方法,否则该子类仍被定义为抽象类。如果子类没有完全抽象抽象类的抽象方法,那么程序在编译时就会报错的!
抽象类的构造方法
abstract class Person{ //定义抽象类
public Person(){
System.out.println("抽象类Person的无参构造方法");
}
}
class Studnet extends Person{
public Studnet(){
System.out.println("子类Studnet的无参构造方法");
}
}
public class Demo {
public static void main(String[] args) {
Studnet s = new Studnet();
}
}
抽象类Person的无参构造方法
子类Studnet的无参构造方法
从程序的运行结果可以看到抽象类是可以定义构造方法的。因为抽象类也存在各种属性,所以子类实例化之前必须要对父类进行实例化。既然抽象类可以定义构造方法,那么
子类就可以通过super关键字调用抽象类的构造方法。
下面我们看一下使用super关键字调用抽象类的构造方法
abstract class Shape{
private float width;
private float height;
public Shape(){
}
public Shape(float width,float height){
this.width = width;
this.height = height;
}
public float getWidth() {
return width;
}
public void setWidth(float width) {
this.width = width;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public abstract void area();
public abstract void zhangchang();
}
class Rectangle extends Shape{
public Rectangle(){
}
public Rectangle(float width,float height){
super(width, height); //调用父类中含有两个参数的构造方法
}
@Override
public void area() { //实现抽象类的面积方法
System.out.println("矩形面积:"+(getWidth()*getHeight()));
}
@Override
public void zhangchang() { //实现抽象类的周长方法
System.out.println("矩形周长:"+((getWidth()*getHeight())*2));
}
}
public class Demo{
public static void main(String[] args) {
Rectangle r = new Rectangle(3.0F,4.0F);
r.area();
r.zhangchang();
}
}
矩形面积:12.0
矩形周长:24.0
抽象类和普通类的区别
使用抽象类和抽象方法需要注意的地方
- 不能调用自身构造方法创建对象,由子类继承后创建对象
- 抽象方法值允许定义方法,不允许实现方法
- 抽象类中不能没有抽象方法,可以有1个或多个
- 若一个类中含有抽象方法,必须声明为抽象类
- 如果一个类继承了抽象类,必须实现该类中所有的抽象方法,否则只能声明为抽象类
接口是抽象概念的进一步深化。Java中的接口主要用来实现类的行为定义,用来约束实现类的行为。接口就像一份契约,约定了类必须实现的功能,但实现类可以根据自身的需求,除了实现接口约定的功能外,还可以实现其他的一些功能。
系统会默认将属性定义为public static final,而将方法默认定义为public abstract
因此接口定义完成后,必须在实现接口的类中对接口中的所有方法进行具体化。也就是说,在实现类中重新定义接口的所有方法,这时这些方法就不是抽象的了,这个过程称为类实现了接口。并且一个类是可以实现多个接口的。
接口之间不能进行实现,但是可以进行继承,并且一个接口可以继承多个接口
public interface A(){
String str = "A"; //默认为public static final 是一个常量
}
public interface B(){
void getInfo(); //默认为public abstract 是一个抽象方法
}
public interface C extends A,B(){
}
上面的这个程序中接口C会继承接口A和接口B内所有的常量和抽象方法,但是接口C不能实现A或B中的任意一个接口,否则会导致编译失败
思考一个问题:Java有了抽象类之后为什么还要引入接口?
简单的来说,就是抽象类我们只能继承一个,但是接口可以实现多个,有时候我们要拥有多个能力或者规则,我们就可以使用接口。如果只是一个,那么接口和抽象类都可以