认识抽象类

1.抽象类的定义

      普通类可以直接产生实例化对象,并且在普通类之中可以包含有构造方法、普通方法、static方
法、常量、变量等内容。而所谓抽象类,就是指在普通类的结构里面增加抽象方法的组成部分。
      所有的普通方法都会有一个“{ }”,这个表示方法体,有方法体的方法一定可以被对象直接使
用,而抽象方法指的是没有方法体的方法,同时还必须使用abstract关键字进行定义。
      拥有抽象方法的类一定属于抽象类,抽象类使用abstract声明。

范例:定义一个抽象类
abstract class A{
     public void fun(){//普通方法
         System.out.println("有方法体的普通方法!");
     }
     public abstract void print();//此方法没有方法体,有abstract关键字,表示抽象方法。
}
范例:抽象类产生对象??
    public class TestDemo{
public static void main(String args[]){
    A a = new A();//A是抽象的,无法实例化
             a.fun();
             a.print();
        }
   }
        这个时候发现程序报错,不能够对A对象实例化。之所以不能够实例化,因为里面有抽象方法,

对象不能够调用没有方法体的方法,也就无从谈实例化对象。

   对于抽象类的使用原则:
      ·抽象类必须有子类;
      ·抽象类的子类,不能是抽象类,必须要覆写抽象类之中的全部抽象方法;
      ·抽象类的对象实例化需要依靠子类完成,采用向上转型的方式处理。


范例:正确使用抽象类
      class B extends A{
              public void print(){
                 System.out.println("Hello World!");
              }
      }
    public class TestDemo{
public static void main(String args[]){
    A a = new B();//向上转型
             a.fun();
             a.print();// 被子类覆写的方法
        }
   }

2. 抽象类的相关限制

   · 抽象类里面由于会存在一些属性,那么在抽象类之中一定会存在构造方法。目的:为属性初
     始化。并且子类对象实例化的时候,依然满足先执行父类构造,再调用子类构造。
   · 抽象类不能使用final定义,因为抽象类必须有子类,而final定义的类不能够有子类。
   · 外部抽象类不允许使用static声明,而内部的抽象类允许使用static声明,使用static声明
     的内部抽象类就相当于外部抽象类。继承的时候,使用“外部类.内部类”的形式表示类名称。
   · 任何情况下,调用类中的static方法的时候,都可以在没有对象的时候直接调用,对于抽象
     类也是一样。
   · 有些时候,由于抽象类只需要一个特定的系统子类操作,所以可以忽略掉外部子类。


范例:static声明内部抽象类
   abstract class A{
          static abstract class B{
               public abstract void print();
          }
   }
   class X extends A.B{
public void print(){
             System.out.println("static声明内部抽象类");
        }
   }
   public class TestDemo {
public static void main(String args[]){
A.B ab = new X(); //向上转型
                ab.print();
        }
   }
范例:忽略抽象类的外部子类
abstract class A{
      public abstract void print();
      private static class B extends A{ //抽象类的内部子类
  public void print(){
System.out.println("Hello World!");
           }
      }
      public static A getInstance(){
 return new B();
      }
   }
   public class TestDemo {
public static void main(String args[]){
                //对外部隐藏了B类
A a = A.getInstance(); //向上转型
                a.print();
        }

   }

请分析下面代码的结果:

     abstract class A{
    public A(){   // 2. 执行父类构造
this.print();  // 3. 调用print()
            }
   public abstract void print();
       }
     class B extends A{
 private int num = 100;
          public B(int num){ // 5.执行子类构造 num = 30;
     this.num = num;
          }
          public void print(){ // 4. 调用覆写的print(),此时num未初始化,num = 0
      System.out.println("num = "+ num); 
          }
     }
     public class TestDemo{
         public static void main(String args[]){
     new B(30).print(); // 1. 执行构造
         }
     }
解决思路:在任何一个类的构造完成之前,所有属性的内容都是其对应数据的默认值,而子类对构造执行之前,一定先执行父类构造。
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值