2011-03-23 6 views
0

Извините, я действительно не знаю, как сделать заголовок для этого вопроса; возможно, есть имя для того, что я пытаюсь сделать, что я не знаю, но я могу объяснить это с помощью некоторого кода:java: «downcasting» к новому объекту/против нарезки

Угадайте, что у вас есть класс, который, к сожалению, не имеет конструктора-копии или общедоступного метода статической копии.

class A 
{ 
    private int i; // <- private, cant access 
    String x;  // <- even worse: cant access unless in same pkg! 
    /* … other stuff, ctor, etc. … */ 
    public A clone() 
    { 
     A a = new A(); 
     a.i = i; 
     a.x = x; 
     return x; 
    } 
} 

Guess дальше, есть некоторая функция, которая возвращает объект этого класса:

public static A someFn(x,y,z); 

Теперь проблема: Я хочу, чтобы извлечь из этого класса, чтобы добавить некоторые функции. К сожалению, у меня тоже нет sizeof в java, а не cc или static copy.

Так что, когда я делаю

class B extends A 
{ 
    protected w; 
    public B clone() 
    { 
     /* as usual */ 
    } 
} 

тогда я могу клонировать мой B и получить новый, но как я могу преобразовать возвратила из someFn() в B. Есть в любом случае сделать напротив нарезки в java? если я клонирую его, это все равно A, и я не могу скопировать его поле по полю. Это все просто в C++, но как это сделать в Java?

+2

Ваш пример слишком абстрактно. У каких конструкторов есть A? Как эти частные и пакетно-частные поля устанавливаются при нормальных обстоятельствах? –

+0

Какой беспорядочный вопрос ... –

+1

Если вы говорите о клонировании в java-смысле, тогда, когда вы вызываете 'super.clone()' в 'B', вы получите' B'. –

ответ

0

к сожалению, единственный оставшийся путь был полный обертка имитируя функциональность мне было нужно, с некоторым куплен над головой в исполнении.

Его укомплектовать тупые, что не существует никакого способа, чтобы обеспечить класс для клонирования, чтобы клонировать в ...

1

В java не используется clone() с использованием оператора new. Надеюсь, у вас есть контроль над исходным классом Java - он не придерживается лучших практик.

Вместо этого вы вызываете super.clone(), который магически возвращает объект правильного типа с результатами предыдущих применений клонов.

См. How to properly override clone method.

3

Либо изменить конструкцию A и B, чтобы быть в состоянии превратить A в B (если это даже смысл: как бы вы превратить собаку в далматин?), Или использовать композицию вместо наследования:

public class B { 
    private A a; 
    private int w; 

    public B(A a, int w) { 
     this.a = a; 
     this.w = w; 
    } 

    public int foo() { 
     return a.foo(); 
    } 

    // ... 
} 
+0

Композиция была бы полезна, если бы java позволил мне перегрузить оператор-литу. Мне все еще нужна возможность дать B для A. – rhavin

+0

Затем сделайте A и B реализуйте один и тот же интерфейс и используйте этот интерфейс в остальной части вашего кода, а не A. Для этого нужны интерфейсы. –

+0

: Да, вы думаете, что вы хотите превратить собаку в собаку-то-есть-ID. – rhavin

1

Во-первых, ваш метод клонирования неверен. Это sould быть что-то вроде:

public A clone(){ 
    A result = (A)super.clone(); 
    result.i = i; 
    result.x = x; 
    return result; 
} 

В то время как клон для B:

public B clone(){ 
    B result = (B)super.clone(): 
    result.w = w; 
    return result; 
} 

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

Тогда вы могли бы назвать someFn (х, у, г), как:

B b = new B(someFn(x, y, z)) 

Кроме того, если someFn не был бы статичным, вы могли бы написать подкласс для класса, который определяет его, и переопределения someFn изменения это тип возвращаемого значения, как (эта функция называется covariant return type):

B someFn(x, y, z){ 
    ... 
} 
+0

Вам не нужно копировать поля из оригинала в клон. super.clone() делает это за вас. –

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