• 15、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?抽象类中是否可以有静态的main方法?


    接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中可以有静态的main方法。

    问:  抽象类是否可继承实体类 (concrete class)

    答: 抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数。

    答案很明确,可以继承。其实从Object就是个实体类,Java的API文档里,每个抽象类的条目里都明确写着直接或间接继承自Object,所以这点是没有疑问的。

    关键在于这答案里所说的“前提是实体类必须有明确的构造函数”一句,是什么意思。

    一般学习者会写的简单试验代码:


    class A{}

    abstract class B extends A{} 

    结果完全正常,编译通过。似乎和“实体类必须有明确的构造函数”完全没有关系。

    这个问题涉及到两个个基础知识:

    1. 所有的class都必须有一个构造方法,如果你没有在代码里声明构造方法,系统会自动给你生成一个公有无参的构造方法。而只要你自己声明了一个构造方法,无论有参无参,私有公有,系统就不再帮你生成默认无参构造器了。

    2.所有的子类构造器都要求在第一行代码中调用父类构造器,如果不写,系统默认去调用父类的无参构造器。

    所以,如果把系统默认配给的方法也算进去,class A{}的代码实际上是

    class A{

      public A(){}

    B继承 A 的时候,则是

    abstract class B extends A{

      public B(){

        super();

      }

    要试验出这继承规则的内部情况,也很简单,在最上面那个简单试验代码里,加上个私有构造器,有参无参都行。

    class A{

      private A(){}


    }

    这个时候,如基础知识(1) 中所说,系统不再给你默认无参构造器, B的构造器根据(2)中的规则去调用super(),却找不到A的无参构造器,所以导致abstract class B extends A{} 编译不能通过。(因为A中没有任何构造器可供子类调用,其实这个时候A只能够供内部类继承,我用的Eclipse的3.4版本会建议给B改名,但是这解决不了这个问题。)

    现在,你应该了解了资料给的那句语焉不详的“实体类必须有明确的构造函数”的含义:

    1.没写构造器的,那是拥有默认无参公有构造函数的,子类可以什么都不写,让默认构造器去调用它。这是最初那两行代码的情况。

    2.写了子类可访问的无参构造器的,也是一样,子类里可以什么都不写,用默认机制调用。

    3.写了 有参构造器却没写无参构造器的,父类里没有子类可访问的无参构造器,子类必须在子类构造器里的第一句写明,调用父类有参构造器,并把参数传进去。

    4.声明为final的以及所有构造器都不在子类访问权限之内的类无法继承

    其实只要是在类的继承中,无论抽象还是实体,都需要符合这个规则的。在这个继承试验中随时删掉或是加上abstract的前缀,结果都没有变化。个人觉得“实体类必须有明确的构造函数”一句实在是无法把这个情况表达清楚,所以广大求职者还是写得清楚些好。

    我喜欢的写法是“可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。” 

    抽象类中可以有静态的main方法。

    public abstract class Test14 {
    
    public static void main(String[] args) {
    System.out.println("abc");
    }
    }

    运行结果:abc

    这个程序可以运行的,你虽然是定义类Test14是抽象的。但是在你类里面是没有抽象方法的,实际你这个类是非抽象的,所以能运行的,如果你定义一个抽象方法fangfa(),并且在main方法中用到这个抽象方法fangfa()时就不能用了.

    abstract 修饰符

    抽象类:

    抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

    一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。

    抽象类可以包含抽象方法和非抽象方法。

    抽象方法

    抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。

    抽象方法不能被声明成 final 和 static。

    任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

    如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。

    抽象方法的声明以分号结尾,例如:public abstract sample();

  • 相关阅读:
    PHP 使用 Redis
    Redis /etc/redis.conf 常用配置
    Redis 常用操作
    Redis 操作哈希数据
    Redis 操作有序集合数据
    Redis 操作集合数据
    Redis 操作列表数据
    Redis 操作字符串数据
    Redis 安装
    Redis 简介
  • 原文地址:https://www.cnblogs.com/helenwq/p/11655532.html
Copyright © 2020-2023  润新知