普通父类与抽象类可以按照常理理解,即被继承的类中存在静态方法,那么就可以用类名以及其继承的子类类名或实例化的对象调用静态方法名。
其中普通类与抽象类不同点在于,普通父类可以实例化,而抽象类不能实例化,正因如此,抽象类无法通过他自己的实例化对象调用。
在jdk8之后可以在接口中写静态方法,因此可以通过接口名调用,但是其实现类无法通过实现类的类名或实现类对象调用,这是由于接口中的静态方法受限,不能继承接口中的静态方法。
在抽象类中,其子类也是无法继承其静态方法的,但是为什么他的子类可以调用呢?我个人理解为,接口可以多继承,若其子类继承了多个接口中的同名静态方法,编译器会无从选择;而抽象类只允许单继承,因此在静态方法的继承方式上,抽象类的子类允许调用抽象类的静态方法,但一般不会这么做,因为静态方法不能被重写,若抽象类的引用指向其子类的实例化,子类中重写了该静态方法,结果会执行父类的静态方法,而非被重写的静态方法。
public class StaticTest {
public static void main(String[] args) {
A a = new A();a.test();
A b = new B();b.test();
B c = new B();c.test();
}
}
class A {
static int i = 10;
public static void test(){
System.out.println("A"+i);
}
}
class B extends A{
public static void test(){
System.out.println("B"+(i+1));
}
}
运行结果为:
A10
A10
B11
回归到我们的主题做测试,尝试做一下普通父类、抽象类以及接口中静态方法的使用规范。
public class AbstractStaticTest {
public static void main(String[] args) {
A.method1();//父类类名调用普通父类的静态方法
new A().method1();//父类对象调用普通父类的静态方法
B.method1();//子类类名调用普通父类的静态方法
new B().method1();//子类对象调用普通父类的静态方法
C.method2();//抽象父类类名调用抽象父类的静态方法
D.method2();//抽象父类C的具体子类类名调用抽象父类的静态方法
new D().method2();//抽象父类C的具体子类调用抽象父类C的静态方法
E.method3();//接口的静态方法只能由接口名调用
// new F().method3;//接口的实现类无法调用接口的静态方法
}
}
class A{//普通父类
public static void method1(){
System.out.println("普通父类的静态方法");
}
}
class B extends A{}//普通父类的子类
abstract class C{//抽象类
public static void method2(){
System.out.println("抽象父类的静态方法");
}
}
class D extends C{}//抽象类的子类
class F implements E{}//接口实现类
public interface E {//接口
public static void method3(){
System.out.println("接口的静态方法");
}
}
运行结果为:
普通父类的静态方法
普通父类的静态方法
普通父类的静态方法
普通父类的静态方法
抽象父类的静态方法
抽象父类的静态方法
抽象父类的静态方法
接口的静态方法
结论:
抽象类和接口无法实例化,但是其类名或接口名均可调用其静态方法;普通父类和抽象类均可利用子类的类名或实例化对象调用其静态方法;接口只允许接口名调用,而无法借用实现类来调用。