抽象类
##1.抽象类的定义与使用
**抽象类:**在普通类的基础上扩充了一些抽象方法(0~n)的类(抽象类是普通类的超集),使用abstract关键字定义。
抽象类不能直接产生实例化对象,因为抽象类是“半成品”,无法直接使用。不能直接new
**抽象方法:**使用abstract 关键字定义并且没有方法体的方法。抽象方法所在类一定是抽象类。
abstract class Person{
public abstract void print();//抽象方法
}
public native void test();//本地方法(调用C或者其他语言同名方法)。也没有方法体
2.抽象类的使用原则
1)所有抽象类必须有子类 :(abstract与final不能同时出现,编译出错)
//抽象类的定义与使用
abstract final class Person{//此处报错 abstract与final关键字不能同时出现
static int num=10;
public abstract void print();
}
public class Test16{
public static void main(String[] args){
System.out.println(Person.num);
}
}
2) 如果子类不是抽象类 ,子类必须覆写抽象类(父类)的所有抽象方法。(子类是抽象类则可以不要求全部覆写)
abstract class Person{
abstract void print();
abstract void fun();
}
class Student extends Person{
static int num=10;
public void print(){}
//public void fun(){}//报错
}
public class Test17{
public static void main(String[] args){
// Person per = new Student();
//Student stu = new Student();
System.out.println(Student.num);
}
}
3)抽象类可以使用子类向上转型对其实现实例化,抽象类一定不能直接实例化对象(无论是否有抽象方法)
abstract class Person{
public abstract void print();
}
class Student extends Person{
public void print(){
System.out.println("hello i am student");
}
}
public class Test19{
public static void main(String[] args){
//Person per = new Student();
Person per = new Person();//此处报错
per.print();
}
}
//正确写法:
public class Test19{
public static void main(String[] args){
Person per = new Student();//正确写法 由子类向上转型实现实例化
per.print();
}
}
4)由于抽象类强制要求子类覆写父类方法,所以private 与 abstract 不能同时使用。(private 修饰私有属性,被private修饰的属性和方法不能被外部使用)
abstract class Person{
private abstract void print();//此时报错 private 与 abstract不能同时使用
}
class Student extends Person{
public void print(){
System.out.println("hello world");
}
}
public class Test18{
public static void main(String[] args){
Person per = new Student();
}
}
抽象类的相关规定
1).抽象类也存在抽象方法,并且子类也一定按照构造实例化流程。先调用抽象类构造方法,再调用子类构造方法。
abstract class Person{
private String name;//属性
public Person(){
System.out.println("父类构造方法!");
}
public void setName(String name){//普通方法
this.name=name;
}
public String getName(){//普通方法
return name;
}
public abstract void print();//抽象方法
}
class Student extends Person{
private int age;
public Student(){//子类构造方法
System.out.println("子类构造方法!");
}
public void setAge(int age){//子类普通方法
this.age=age;
}
public int getAge(){//子类普通方法
return age;
}
public void print(){//子类覆写的父类抽象方法
//空实现
}
}
public class Test20{
public static void main(String[] args){
new Student();
}
}
2).特殊代码
abstract class A{
public A(){//3.调用父类构造方法
this.print();//4.调用父类方法,方法被子类覆写
}
public abstract void print();
}
class B extends A{
private int num=100;
public B(int num){//2.调用子类构造方法
super();//3.隐含调用父类构造方法
this.num=num;//为类中属性初始化
}
public void print(){//5.调用覆写后的方法。此时子类对象的属性没有被初始化(对象初始化操作在构造方法中执行)
System.out.println(this.num);//6.打印数据为数据类型的默认值
}
}
public class Test21{
public static void main(String[] args){
new B(30);//1.实例化子类对象
new B(30).print();//修改代码后
}
}
结果为 0 原因:此时子类对象的属性没有被初始化,即没有进入子类的构造方法中。
3).补充:关于对象实例化:对象的实例化操作有以下几个核心步骤:
- ·进行类加载
- 进行类对象的空间开辟
- 进行类对象中属性初始化(构造方法)
4).抽象类中允许不定义任何抽象方法,此时该抽象方法仍然不能直接创建实例化对象
abstract class Person{
private int num;
public void fun(){
System.out.println("*******");
}
}
class Student extends Person{
public void fun(){
System.out.println("&&&&&&&");
}
}
public class Test22{
public static void main(String[] args){
Person per = new Person();//此处报错
}
}
5). 抽象类一定不能使用final 关键字声明,因为用final声明的类不允许有子类,而抽象类必须有子类;
抽象类一定不能使用private 关键字声明,因为private 关键字表示封装,内部操作外部不可见,而抽象方法 必须被覆写。
6).抽象类也分内部抽象类和外部抽象类。内部抽象类的抽象方法与外部抽象类的抽象方法无关。**当前直接继承哪个抽象类,就覆写其抽象方法。**即:若直接继承外部抽象类,则只需覆写外部抽象类的所有抽象方法即可
abstract class A{//外部抽象类
public abstract void fun();
abstract class AInner{//内部抽象类
abstract void fun1();
}
}
class B extends A{//子类
public void fun(){//只覆写外部类的抽象方法
System.out.println("0000");
}
}
public class Test23{
public static void main(String[] args)
}
}
//此时程序不报错
//修改程序
class B extends A{
/*public void fun(){
System.out.println("0000");
} */
public void fun1(){};//覆写内部抽象类的抽象方法 程序报错
}
//要覆写内部抽象类抽象方法 正确写法
abstract class A{
public abstract void funA();
abstract class AInner{
public abstract void funB();
}
}
class B extends A{
public void funA(){};
class BInner extends AInner{
public void funB(){};
}
}
public class Test24{
public static void main(String[] args){
}
}
7).外部类抽象类不允许使用static ,内部类抽象类可以使用static
abstract class A{
public abstract void print();
static abstract class B{//内部抽象类
public abstract void printB();
}
}
class C extends A.B{
public void printB(){};
}
public class Test25{
public static void main(String[] args){
C c = new C();
}
}