2015-07-10 2 views
3

У меня есть BaseObj:как эффективно использовать перегрузку и полиморфизм

public abstract class BaseObj { 
    String name; 
    public BaseObj(String _name) { 
     name = _name; 
    } 

    public void report(){ 
     System.out.println(name + " is " + getType()); 
    } 

    public abstract String getType(); 

} 

и два подкласса Sample1 и Sample2:

public class Sample1 extends BaseObj{ 
    private float var; 
    public Sample1(String name,float _var){ 
     super(name); 
     var = _var; 
    } 

    @Override 
    public String getType() { 
     return "Float: " + Float.toString(var); 
    } 
} 

и

public class Sample2 extends BaseObj{ 
    private int var; 
    public Sample2(String name , int _var){ 
     super(name); 
     var = _var; 
    } 

    @Override 
    public String getType() { 
     return "Integer: " + Integer.toString(var); 
    } 

} 

в главном Calss:

public class Poly { 
    public static void main(String[] args){ 
     BaseObj mObj[] = new BaseObj[4]; 

     // Hard-definition of the object tyte 
     mObj[0] = new Sample1("X1",(float)12.34); 
     mObj[1] = new Sample2("X2",12); 
     mObj[2] = new Sample2("X3",12); 
     mObj[3] = new Sample1("X4",(float)1.2); 

     for(BaseObj x:mObj){ 
      x.report(); 
     } 
    } 
} 

Мне нужно определить тип элементов mObj. Но я ищу способ, используя overload, чтобы избежать такого рода трудного дефининга, например. в новом классе я использовать перегрузку, чтобы получить правильный объект на основе его входов:

public class Sample{ 
    public Sample(String _name , int _var){ 
     // get Sample2 object 
    } 
    public Sample(String _name , float _var){ 
     // get Sample1 object 
    } 
} 

тогда я смог бы изменить код моего основного Calss следующим образом:

public class Poly { 
    public static void main(String[] args){ 
     BaseObj mObj[] = new BaseObj[4]; 

     mObj[0] = new Sample("X1",(float)12.34); 
     mObj[1] = new Sample("X2",12); 
     mObj[2] = new Sample("X3",12); 
     mObj[3] = new Sample("X4",(float)1.2); 

     for(BaseObj x:mObj){ 
      x.report(); 
     } 
    } 
} 

выход в настоящее время следующим образом:

X1 is Float: 12.34 
X2 is Integer: 12 
X3 is Integer: 12 
X4 is Float: 1.2 

Edit: что именно мне нужно, чтобы определить элементы mObj в new Sample("X1",var) и не некоторые из них, как new Sample1("X1",(float)12.34) и некоторые, как new Sample2("X1",12). Для этого я решаю вопрос о типе моего объекта в конструкторах класса Sample. У кого-нибудь есть идея? Спасибо

+0

Что вы ожидали от вас? Вы перегрузили свой конструктор, и он, похоже, делает то, о чем вы просили. –

+0

@PeterLawrey Я думаю, они спрашивают, есть ли способ избежать «нового образца (....)» кода в их основном классе. Они пытаются выяснить, могут ли они компилятором неявно узнать, какой тип каждого элемента в 'mObj'. Я думаю – Marcin

+0

@Marcin Невозможно избежать использования конструктора или статического заводского метода для создания объекта. Java не поддерживает создание объектов с помощью каста (кроме автоматического бокса) –

ответ

1

Я думаю, что вы ищете здесь метод фабрики.

public class BaseObjFactory { 
    public static BaseObj create(String name, int value) { 
     return new Sample2(name, value); 
    } 

    public static BaseObj create(String name, float value) { 
     return new Sample1(name, value); 
    } 
} 

и использовать его таким образом

mObj[0] = BaseObjFactory.create("X1",12.34f); 
mObj[1] = BaseObjFactory.create("X2",12); 
mObj[2] = BaseObjFactory.create("X3",12); 
mObj[3] = BaseObjFactory.create("X4",1.2f); 

КСТАТИ. нет необходимости использовать литой (float)1.2, просто добавьте f, чтобы сделать его float буквальным.

+0

Это швы это то, что мне нужно, спасибо! но не могли бы вы объяснить первую часть своего кода? – Behy

+0

Это определение Factory, я использую два перегруженных метода 'create' для создания экземпляров экземпляров, поэтому компилятор выберет правильный. – tilois

1

Использовать заводские методы.

class SampleFactory { 
    Sample1 create(String name, int value) { 
     return new Sample1(name, value); 
    } 

    Sample2 create(String name, float value) { 
     return new Sample2(name, value); 
    } 
} 

Затем вы можете использовать его в качестве

mObj[0] = SampleFactory.create("X1",(float)12.34); 
mObj[1] = SampleFactory.create("X2",12); 
mObj[2] = SampleFactory.create("X3",12); 
mObj[3] = SampleFactory.create("X4",(float)1.2); 
0

Я предлагаю вам начать с самим простым решением для того, что вы пытаетесь достичь.

public class Poly { 
    public static void main(String[] args) { 
     Sample[] mObj = { 
       new Sample("X1", 12.34f), 
       new Sample("X2", 12), 
       new Sample("X3", 12), 
       new Sample("X4", 1.2f) 
     }; 

     for (Sample x : mObj) 
      x.report(); 
    } 
} 

class Sample { 
    private final String desc; 
    private final Number value; 

    public Sample(String desc, Number value) { 
     this.desc = desc; 
     this.value = value; 
    } 

    public void report() { 
     System.out.println(desc + " is a " + value.getClass().getSimpleName() + ": " + value); 
    } 
} 

печатает

X1 is a Float: 12.34 
X2 is a Integer: 12 
X3 is a Integer: 12 
X4 is a Float: 1.2 

Это использует полиморфизм в этом Float и Integer являются подклассами Number.

+0

вне курса мой код - не самое простое решение, но я просто упростил свой код, чтобы объяснить проблему. В моем оригинале у меня есть else вместо getType() – Behy

Смежные вопросы