簡體   English   中英

Java繼承,如何重寫子類中的方法

[英]Java inheritance, how to override a method in subclass

我正在研究實習面試問題。 問題是僅使用一個以上的堆棧進行臨時存儲來實現排序的堆棧。

實現的描述:我正在擴展Stack類以實現SortedStack類。 SortedStack類的大多數方法與Stack類相同,因此我不需要實現它們。 僅推入方法被覆蓋。

在我的實現中,我將當前堆棧傳遞給push方法。 我的問題是:這是訪問現有堆棧的最佳方法。 我可以在不將其傳遞給push()方法的情況下訪問其內容嗎?

Node.java

public class Node {
    private int key;
    private float value;

    public Node(int key, float value) {
        this.key = key;
        this.value = value;
    }

    public int getKey() { return key; }
    public void setKey(int key) { this.key = key; }

    public float getValue() { return value; }
    public void setValue(float value) { this.value = value; }
}

SortedStack.java

import java.util.Stack;

public class SortedStack extends Stack {

    public SortedStack() {
        super();
    }

    public void push(Stack<Node> mainStack, Node newNode) {
        Stack<Node> tempStack = new Stack<Node>();

        while (!mainStack.isEmpty()) {
            if (mainStack.peek().getKey() > newNode.getKey()) {
                tempStack.push(mainStack.pop());
            }
            else {
                break;
            }
        }

        mainStack.push(newNode);

        while (!tempStack.isEmpty()) {
            mainStack.push(tempStack.pop());
        }
    }

}

SortedStackApp.java

public class SortedStackApp {

    public static void main(String[] args) {

        SortedStack stack = new SortedStack();

        stack.push(stack, new Node(10, 1.1f));
        stack.push(stack, new Node(80, 1.8f));
        stack.push(stack, new Node(50, 1.5f));
        stack.push(stack, new Node(90, 1.9f));
        stack.push(stack, new Node(20, 1.2f));
        stack.push(stack, new Node(30, 1.3f));

        Node node = null;

        while (!stack.isEmpty()) {
            node = (Node) stack.pop();
            System.out.printf("(%d, %3.1f) ", node.getKey(), node.getValue());
        }
        System.out.println();
    }
}

堆棧是java.util.Stack,如以下網址所述: http : //docs.oracle.com/javase/7/docs/api/java/util/Stack.html

首先,如果要擴展java.util.Stack ,則應為其提供基本類型。 這是錯誤的:

public class SortedStack extends Stack {...}

在這種情況下, Stack原始類型 原始類型只能與遺留代碼一起使用,因為這樣會失去類型安全性。 相反,您應該使用:

public class SortedStack extends Stack<Node> {...}

這樣做將自動使您的堆棧僅接受Node元素。

就像我在評論中說的那樣,您應該重寫 push方法,而不要重載它。 這意味着它必須具有與父類的push方法完全相同的參數。 因此,它僅應采用Node參數,僅此而已。 使用@Override批注標記該方法,以確保您確實覆蓋了該方法,並且未超載。 如果您有其他參數或不兼容的參數類型,則編譯器將發出錯誤。

您會注意到,一旦這樣做,就必須更改方法的聲明以也返回Node ,因為這是在java.util.Stack聲明push方式。

因此,您的方法應為:

@Override
public Node push(Node n) {
   ...
}

您應該使用以下命令從main調用它:

stack.push( new Node( 10, 1.1f ) );

由於您已經使用類型正確聲明了它,因此無需將pop的結果popNode

node = stack.pop(); // No need for (Node)

現在我們有了一個正確鍵入的類,那么,您的項目就是堆棧。 這就是繼承的真正含義:“我現在正在編寫的這個類是一個Stack ,它具有所有Stack方法,並存儲了所有Stack數據,我只是在更改其某些行為。”

因此,訪問“主”堆棧只需要訪問自身即可 例如,您的while循環應為:

    while (!this.empty()) {
        if (this.peek().getKey() > n.getKey()) {
            tempStack.push(this.pop());
        }
        else {
            break;
        }
    }

實際上,您也可以擺脫this因為沒有歧義。 調用empty()與調用this.empty()相同(您在代碼java.util.Stack使用了isEmpty() ,但java.util.Stack僅具有empty() )。

所以實際上應該是:

    while (!empty() && peek().getKey() > n.getKey() ) {
        tempStack.push(pop());
    }

(我對您的循環進行了一些改進,如果沒有多余的if )。

但是,提防使用this.push()或只是push()來獲取主堆棧。 您可以改用super.push() 這樣,它將使用原始行為push項目push送到實際堆棧中:

    super.push(n); // Don't use new Node() here. Push the node you were given.

    while (!tempStack.empty()) {
        super.push(tempStack.pop());
    }

如果您不這樣做,您將遞歸調用與您現在正在編寫的相同的push 這不是您想要的-您希望在內部使用“普通”按鈕。

完成后,請記住返回您插入的Node

另一個選擇是不擴展Stack而是重新實現所有方法並具有內部堆棧。 查找“組成與繼承”,以確定哪個更好。

這是唯一的方法。 您無法訪問直接數據,因為直接數據作為私有存儲在節點中,然后被發送到堆棧

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM