61784


_Product_ という親クラスと、 _Product_ を継承する _FoldingBike_ という子クラスが存在しているのですが、
_FoldingBike_ で施されたgetGear()というコンストラクタを親クラスである _Product_
で使いたいと考えております。*this.getGear()*で出来ると考えていたのですがエラーとなってしまいます。

[code]

    public class Product {
    
        String brand;
        int weight;
        Boolean light; 
        String color;
        int price;
    
        public Product(String brand, int weight, Boolean light, String color, int price) {
            this.brand  = brand;
            this.weight =weight;
            this.light = light;
            this.color = color;
            this.price = price;
        }
    
        public String toString() {
    
            String result = this.getGear();
            }
        }
    
    
    public class FoldingBike extends Product {
    
        int size;
        int gear;
    
        public FoldingBike(String brand, int weight, Boolean light, String color, int price, int size, int gear) {
    
            super(brand, weight, light, color, price);
            this.size = size;
            this.gear = gear;
        }
    
        public int getSize() {
            return size;
        }
    
        public int getGear() {
            return gear;
        }
    
    
    }
    
    
    
    
[/code]


CC BY-SA 4.0
2019-12-25T18:41:17.833
61771
2020-01-03T20:14:24.317
36172
question
java
Java 継承について


## `getGear()`というコンストラクタ

「コンストラクタ」ではなく、メソッドですが、通常のオブジェクト指向言語で「継承」と言うのは、「親から子へ」とメソッドなどが引き継がれることを指します。「子から親へ」継承されることはありません。(実験レベルのマイナーな言語ではあるかもしれませんが。)

あなたのコードで言うと、`Product`のインスタンスには`gear`なんてフィールドは無い訳ですが、それに対して`getGear()`を呼び出すと、一体どんな値が返ってくるのでしょうか?

例えば「無かったら0とかで良い」と言うのであれば、親クラスである`Product`側に`getGear()`を定義しておかないといけません。

[code]

    public class Product {
    
        String brand;
        int weight;
        boolean light; 
        String color;
        int price;
    
        public Product(String brand, int weight, boolean light, String color, int price) {
            this.brand  = brand;
            this.weight = weight;
            this.light = light;
            this.color = color;
            this.price = price;
        }
    
        @Override
        public String toString() {
            String result = String.valueOf(this.getGear());
            return result;
        }
    
        public int getGear() {
            return 0;
        }
    }
    
[/code]

こうすると子クラス側の`getGear()`は継承したメソッドをオーバライドしていることになります。

(今回の問題とは直接関係ないですが、lightの定義に`Boolean`を使う必要はないと思われたので、`boolean`に書き換えてあります。(大文字の)`Boolean`が必要になることは滅多にありませんが、もしそちらが必要なのであれば理由を教えてください。)

子クラスのメソッドを親クラスで使おうとするあたり、まだ継承に関する理解が不十分なように思われます。この回答で分かりにくい点があれば、コメントするなり、質問文を編集して情報を付け足すなりしてお知らせください。


CC BY-SA 4.0
2019-12-25T22:34:38.613
61775
2019-12-25T22:34:38.613
13972
61771
answer


`Product` に、抽象メソッドとして `getGear()` を宣言する

[code]

    public abstract int getGear();
    
[/code]

ことで `Product` のメソッドでも `getGear()` が存在するとみなせるようになります。

`new FoldingBike(...)` で作成したオブジェクトであれば `getGear()` は `FoldingBike` の
`getGear()` が用いられ、想定通りの挙動になるかと思います。

ただしこのとき `Product` 自身は `getGear()` の実装を持っていないのでインスタンス化できません(つまり、`new
Product(...)`はコンパイルエラーになります)。

[code]

    // "abstract" を付与する必要あり
    public abstract class Product {
    
        // 省略
    
        @Override
        public String toString() {
    
            final int gear = this.getGear();
            // ...
        }
    
        // Prductを継承した具象クラス(今回の場合FoldingBike)で実装しています、という宣言
        public abstract int getGear();
    
        public abstract int getSize();
    }
    
[/code]

* * *

抽象メソッド/抽象クラス についての公式の説明はこちらになります(英語):

  * [Abstract Methods and Classes (The Java™ Tutorials >   
Learning the Java Language > Interfaces and
Inheritance)](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)

(補足: 比較的基本的な概念なので、検索すれば日本語の解説も多くあるかと思います)

基底クラスである `Product` では `FoldingBike`
やその他派生クラス全てが持つ共通のふるまい/性質を表現しますが、それらのうちの一部の実装は派生クラスごとに異なる、という場合に利用します。

`Product` は必ず `gear` も `size`
も持っている(数えることができる)が、その持ち方(数え方)は、プロダクトの種類(折り畳み自転車なのか、別のプロダクトなのか)によって異なる、ような場合に利用できる手段です。


CC BY-SA 4.0
2019-12-26T02:31:27.717
61784
2020-01-03T20:14:24.317
2020-01-03T20:14:24.317
2808
2808
61771
answer