抽象类的定义与使用

抽象类

##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(); 
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值