Java, как заставить аргумент метода принимать тип подкласса и суперкласс - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть суперкласс и один подкласс с некоторыми переменными, как показано ниже:

public class A{

    private int first;
    private int second;

    public A(int _first, int _second){
        first = _first;
        second = _second;
    }

    public int getFirst(){
        return first;
    }

}

public class B extends A{

    private int third;

    public B(int _first, int _second, int _third){
        super(_first, _second);
        third = _third;
    }

    public int getThird(){
        return third;
    }

}

Я хочу построить метод в главном классе, который принимает универсальный аргумент, который может иметь тип A или типB как показано ниже:

public class Main{

    public int val = 2;

     public static void main(String []args){
        A a = new A(1, 2);
        B b = new B(1, 2, 3); 

        printObject(a);
        printObject(b);

     }

     public void printObject(A a){

         int f = a.getFirst() * val;
         int s = a.getSecond() * val;

         if(a instanceOf B){
             int t = a.getThird() * val; // compiler does not find the getThird() method this way
         }
     }
}

Как этого достичь ?. это дженерики вариант? Я думал о создании метода printObject() внутри A, а затем переопределил его внутри B, однако у меня есть другая переменная, такая как val выше, которую я создаю в main.

update

Я пытался использовать instanceOf как вышеописанный метод. Но таким образом компилятор не находит специфический метод подкласса.

Ответы [ 3 ]

0 голосов
/ 05 ноября 2019

Все намного проще) Вы можете избавиться от этого метода в главном классе, потому что он производит некоторую избыточную связь. И все это instanceof действительно пахнет в 2019 году. Вы можете сделать его более независимым.

Класс A:

public class A{

    private int first;
    private int second;

    public A(int _first, int _second){
        first = _first;
        second = _second;
    }

    public int getFirst(){
        return this.first;
    }

    public int getSecond(){
        return this.second;
    }

    public void print(int multiplier) {
        System.out.println(this.first * multiplier);
        System.out.println(this.second * multiplier);
    }

}

Класс B:

public class B{

    private int third;

    public B(int _first, int _second, int _third){
        super(_first, _second);
        third = _third;
    }

    public int getThird(){
        return this.third;
    }

    @Override
    public void print(int multiplier) {
        super.print(multiplier);
        System.out.println(this.third * multiplier);
    }

}

Класс Main:

   public class Main{

         public int val = 2;

         public static void main(String []args){
            A a = new A(1, 2);
            B b = new B(1, 2, 3); 

            a.print(val);
            b.print(val);

         }
   }
0 голосов
/ 05 ноября 2019

Написание объектно-ориентированного кода - это больше, чем расширение класса, ваш API и другие функциональные возможности должны быть разработаны как часть решения.

В вашем случае наиболее подходящий способ сделать это - добавить печатьВ методе самого объекта вы можете либо переопределить всю функцию, либо вызвать суперкласс внутри переопределяющего класса.

public class A{
    /// ... your code

 public void print(){
    System.out.println("first :"+first+", second : "+second);
}
}

public class B extends A{
     /// ... your code
    public void print(){
       //Option A - use parent class getters/setters to implement print for object B
       System.out.println("first :"+super.getFirst()+", second : "+super.getsecond() +" third" + third);
      }

      //Option B (More usable to methods returning a value or performing an update) - Perform operation on parent variables, then perform on class specific variables       
       super.print()
       System.out.println("third : "+third);
    }    


}

, а затем

A a  = new A();
A b = new B();

a.print();
b.print();

Будет ли каждый вызывать правильную среду выполненияфункция, основанная на их фактической реализации

0 голосов
/ 05 ноября 2019

Во-первых, по определению, если вы объявляете A как параметр для любого метода, а B является его подклассом, тогда любой A или B может быть передан этому методу.

Вы могли бы затем достичь желаемого с помощью оператора instanceof (чтобы проверить, имеет ли передаваемый параметр тип B). Однако, как правило, следует использовать переопределение наследования / метода, а не instanceof.

Вы можете передать 'val' в методы printObject () в A / B. Если задействованы несколько переменных, таких как 'val', вы можете передать другой объект или, возможно, вам нужно разделить код по нескольким методам в классе A (переопределить в B), передавая различные значения в зависимости от ситуации? (Обычно вы не выполняете вычисления в методе, целью которого является печать объекта, но, возможно, это был просто пример?)

...