抽象类(abstract class)

抽象类的由来

  • 利用抽象类是为了更好的对类加以分类,就如同人类不但给各种具体植物取了名字还发明了“植物”这个抽象的词对所有具体植物进行归类一样
  • Java用来模拟现实世界,所以也存在抽象类
  • 抽象类通常用来作为一个类族的最顶层的父类,用最底层的类表示现实中的具体事物,用最顶层的类表示该类族所有事物的共性

抽象方法与抽象类

  • 抽象方法
  • 在定义Java方法时可以只给出方法头,而不给出方法内部实现代码,这样的方法称为抽象方法
  • 凡是没有方法体的方法必须的使用关键字abstract修饰为抽象方法
  • 凡是含有抽象方法的类都必须的声明为抽象类
  • 抽象类
  • 用abstract关键字来修饰一个类时,该类叫做抽象类
  • 包含抽象方法的类必须声明为抽象类
  • 但是一个抽象类却可以不包含任何抽象方法,尽管比较少见
  • 抽象类不一定有抽象方法
  • 有抽象方法的一定是抽象类
abstract class A
{
    abstract public void f();
}
class B extends A
{
    public void f()
    {
        System.out.printf("BBBB\n");
    }
}

public class M
{
    public static void main(String[] args)
    {
        A aa = new A();
    }
}

程序运行示例:
  ——————————————————————————
  M.java:17: 错误: A是抽象的; 无法实例化
        A aa = new A();
               ^
1 个错误
  ——————————————————————————
abstract class A
{
    abstract public void f();
}
class B extends A
{
    public void f()
    {
        System.out.printf("BBBB\n");
    }
}

public class M
{
    public static void main(String[] args)
    {
        // A aa = new A(); //error 17行
        B bb = new B(); //OK
        bb.f();         //OK

        A aa;       //21 行 ok 可以定义一个抽象类的引用,但是不可以定义一个抽象类的对象,所以17行error,本行OK
        aa = bb;
        aa.f();
    }
}

程序运行示例:
  ——————————————————————————
BBBB
BBBB
  ——————————————————————————

Final

final可以修饰

1、整个类

2、类中的若干个属性

3、类中的若干个方法

Final修饰整个类

  • 表示该类不能被继承
  • 如果认为一个类已经很完美且不需要定义子类来继承它时,可以使用它
  • 格式
public final class A
{}
public 和 final 可以互换
final class A
{

}
class B extends A
{
    public void f()
    {
        System.out.printf("BBBB\n");
    }
}

public class M
{
    public static void main(String[] args)
    {

    }
}

程序运行示例:
  ——————————————————————————
M.java:5: 错误: 无法从最终A进行继承
class B extends A
                ^
1 个错误
  ——————————————————————————

Final修饰类中的若干个属性

  • Final修饰类中的若干属性表示该属性必须被赋值并且只能被赋一次值(注意默认值0不是真正的赋值)
  • 初始化方式有两种:(只能选择其中的一种)
  • 在定义成员变量的同时初始化
  • 在类中所有的构造函数中初始化
  • 注意:
  • 一个类的所有普通方法内部都不可以修改final修饰过的成员变量的值
final class A
{
    final public int i; //error  常变量  等价于C:const
    // final public int i = 10;//OK  常变量  等价于C:const
    public A(int i)
    {
        this.i = i;
    }
    public void f()
    {
        // i = 22;
    }


}

public class M
{
    public static void main(String[] args)
    {
        A aa = new A(100);
        System.out.printf("%d\n",aa.i);
    }
}

程序运行示例:
  ——————————————————————————
100
  ——————————————————————————

Final修饰类中的若干个方法

  • 表示该方法可以被子类继承,但不可以被子类重写
  • 例子:
class A
{
    final public void f()// 如果在public前面加final,则编译时就会报错
    {
        System.out.printf("AAAA\n");
    }
}
class B extends A
{
    public void f() //重写父类的方法
    {
        System.out.println("BBBB");
    }
}
public class M
{
    public static void main(String[] args)
    {
        
    }
}
程序运行示例:
  ——————————————————————————
M.java:10: 错误: B中的f()无法覆盖A中的f()
    public void f() //重写父类的方法
                ^
  被覆盖的方法为final
1 个错误
  ——————————————————————————