1. 程式人生 > >java中繼承static member與method

java中繼承static member與method

java中不能重寫static member與method。

1.Inheritance

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. You can 1.use the inherited members as is

, 2.replace them, 3.hide them, or 4.supplement them with new members:

1.The inherited fields can be used directly, just like any other fields.
2.You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).
3.You can declare new fields in the subclass that are not in the superclass.
4.The inherited methods can be used directly as they are.
5.You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
6.You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
7.You can declare new methods in the subclass that are not in the superclass.
8.You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.

關於Private Members in a Superclass

兩種情況subclass可以引用private member或者method:

1.if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.即spuerclass有public或者protected方法來對private field進行操作。

2.因為內部類可以操作外部類的private field,所以,a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.

2.Multiple Inheritance of State, Implementation, and Type

One significant difference between classes and interfaces is that classes can have fields whereas interfaces cannot.

如果多繼承,那麼多個父類中相同的field到底哪個先實現呢?因為java介面中沒有field,並且只能是單繼承類,所以避免了多繼承中需要解決的這個問題。

但是真的解決了嗎?因為java可以實現多個介面,還是會導致同名method的混用。java怎樣解決呢?參考Default Methods

下面是Default methods:
介面的default method時java8的新特性。
Default methods introduce one form of multiple inheritance of implementation. A class can implement more than one interface, which can contain default methods that have the same name. The Java compiler provides some rules to determine which default method a particular class uses.

package defaultmethods;

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }
    //在介面中使用default來實現預設方法    
    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

You specify that a method definition in an interface is a default method with the default keyword at the beginning of the method signature. All method declarations in an interface, including default methods, are implicitly public, so you can omit the public modifier.介面預設方法實現是java8的新特性。注意跟java的包許可權區別開來。

any class that implements the interface TimeClient, will have the method getZonedDateTime already defined.

對於一個介面繼承自一個帶有預設方法的介面(注意是介面之間的繼承),我們可以有以下改動:

1.Not mention the default method at all, which lets your extended interface inherit the default method.
2.Redeclare the default method, which makes it abstract.
3.Redefine the default method, which overrides it.

情況1:

public interface AnotherTimeClient extends TimeClient { }

Any class that implements the interface AnotherTimeClient will have the implementation specified by the default method TimeClient.getZonedDateTime.

情況2:

public interface AbstractZoneTimeClient extends TimeClient {
    public ZonedDateTime getZonedDateTime(String zoneString);
}

Any class that implements the interface AbstractZoneTimeClient will have to implement the method getZonedDateTime; this method is an abstract method like all other nondefault (and nonstatic) methods in an interface.重新使在原介面中預設的方法變為abstract。

情況3:

public interface HandleInvalidTimeZoneClient extends TimeClient {
    default public ZonedDateTime getZonedDateTime(String zoneString) {
        try {
            return ZonedDateTime.of(getLocalDateTime(),ZoneId.of(zoneString)); 
        } catch (DateTimeException e) {
            System.err.println("Invalid zone ID: " + zoneString +
                "; using the default time zone instead.");
            return ZonedDateTime.of(getLocalDateTime(),ZoneId.systemDefault());
        }
    }
}

Any class that implements the interface HandleInvalidTimeZoneClient will use the implementation of getZonedDateTime specified by this interface instead of the one specified by the interface TimeClient.相當於重寫了原來的default方法。

除了在interface中新增default method,還可以新增Static Methods。

The Java programming language supports multiple inheritance of type, which is the ability of a class to implement more than one interface. An object can have multiple types: 1.the type of its own class and 2.the types of all the interfaces that the class implements.

3.Overriding and Hiding Methods

Instance Methods

正常的重寫父類的例項方法

Static Methods

If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.

The distinction between hiding a static method and overriding an instance method has important implications:

1.The version of the overridden instance method that gets invoked is the one in the subclass.
2.The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.

這個hide是什麼意思呢?看程式碼:

class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }
    public static void main(String[] args){
    Cat myCat = new Cat();
        Animal myAnimal = myCat;
        //試驗static method
        Animal.testClassMethod();
        Cat.testClassMethod();
        myAnimal.testClassMethod();
        myCat.testClassMethod();
        myAnimal.testInstanceMethod();
}

}

輸出:

The static method in Animal
The static method in Cat
The static method in Animal
The static method in Cat
The instance method in Cat

可以看出hide的意思,跟靜態繫結差不多。呼叫的方法都是靜態宣告的形式

Interface Methods

when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict(解決命名衝突). These rules are driven by the following two principles:

1.Instance methods are preferred over interface default methods.例項方法優先

public class Horse {
    public String identifyMyself() {
        return "I am a horse.";
    }
}
public interface Flyer {
    default public String identifyMyself() {
        return "I am able to fly.";
    }
}
public interface Mythical {
    default public String identifyMyself() {
        return "I am a mythical creature.";
    }
}
public class Pegasus extends Horse implements Flyer, Mythical {
    public static void main(String... args) {
        Pegasus myApp = new Pegasus();
        System.out.println(myApp.identifyMyself());
    }
}

The method Pegasus.identifyMyself returns the string I am a horse.

2.Methods that are already overridden by other candidates are ignored.(被重寫的方法會被忽略,也就是會呼叫最新的方法,可以這樣理解吧) This circumstance can arise when supertypes share a common ancestor.

public interface Animal {
    default public String identifyMyself() {
        return "I am an animal.";
    }
}
public interface EggLayer extends Animal {
    default public String identifyMyself() {
        return "I am able to lay eggs.";
    }
}
public interface FireBreather extends Animal { }
public class Dragon implements EggLayer, FireBreather {
    public static void main (String... args) {
        Dragon myApp = new Dragon();
        System.out.println(myApp.identifyMyself());
    }
}

The method Dragon.identifyMyself returns the string I am able to lay eggs.

If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods.沒有繼承關係的情況下,如果出現衝突,必須顯式制定呼叫的方法。

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}
public interface FlyCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}

A class that implements both OperateCar and FlyCar must override the method startEngine. You could invoke any of the of the default implementations with the super keyword.

public class FlyingCar implements OperateCar, FlyCar {
    // ...
    public int startEngine(EncryptedKey key) {
        FlyCar.super.startEngine(key);
        OperateCar.super.startEngine(key);
    }
}

還有一種情況:

public interface Mammal {
    String identifyMyself();
}
public class Horse {
    public String identifyMyself() {
        return "I am a horse.";
    }
}
public class Mustang extends Horse implements Mammal {
    public static void main(String... args) {
        Mustang myApp = new Mustang();
        System.out.println(myApp.identifyMyself());
    }
}

The method Mustang.identifyMyself returns the string I am a horse. The class Mustang inherits the method identifyMyself from the class Horse, which overrides the abstract method of the same name in the interface Mammal.因為繼承了父類的方法,相當於實現了Mammal介面中的抽象方法,因為同名啊。

Note: Static methods in interfaces are never inherited.在介面中的static method不需要在繼承類或者介面中實現之。

Modifiers

The access specifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the superclass can be made public, but not private, in the subclass.access只能更大,不能更小。

總結
這裡寫圖片描述

Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.可以過載從superclass繼承的方法,這樣的過載不算hide或者重寫父類的方法。

4.Hiding Fields

Within a class, a field that has the same name as a field in the superclass hides the superclass’s field, even if their types are different(即使物件type不同,子類同樣會hide同名的屬性). Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super(因此同名的屬性引用時必須用super), which is covered in the next section. Generally speaking, we don’t recommend hiding fields as it makes code difficult to read.不推薦hide field。

Accessing Superclass Members

If your method overrides one of its superclass’s methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged). 方法同名發生重寫,field同名就會發生hide,這時需要使用super,但不鼓勵這樣寫。

5.Writing Final Classes and Methods

6.Summary of Inheritance