Переопределение и generic-и
От: ojow  
Дата: 11.03.09 05:34
Оценка:
Допустим, нам надо сделать интерфейс, который бы позволял объекту копировать себя в объекты его (или ниже по наследованию) класса. Простейшая реализация будет в таком духе:

import org.junit.Test;   
import org.junit.internal.runners.JUnit4ClassRunner;   
import org.junit.runner.RunWith;   
   
@RunWith(JUnit4ClassRunner.class)   
public class TestGenerics {   
public static interface Copyable {   
        public void copy(Copyable c);   
}   
   
public static class A implements Copyable {   
        private String aField = "--A--";   
        protected void innerCopy(Copyable c) {   
                A a = (A)c;   
                System.out.println(a.aField);   
        }   
        public void copy(Copyable c) {   
                innerCopy(c);   
        }   
}   
   
public static class B extends A {   
        private String bField = "--B--";   
        protected void innerCopy(Copyable c) {   
                B b = (B)c;   
                super.innerCopy(b);   
                System.out.println(b.bField);   
        }   
}   
   
@Test   
public void testCopy() {   
        Copyable b1 = new B();   
        Copyable b2 = new B();   
        b1.copy(b2);   
}   
}


Я решил попробовать пошаманить с generic-ами и смог добиться того же результата таким образом:

import org.junit.Test;   
import org.junit.internal.runners.JUnit4ClassRunner;   
import org.junit.runner.RunWith;   
   
@RunWith(JUnit4ClassRunner.class)   
public class TestGenerics {   
    public static interface Copyable<T> {   
        public void copy(T t);   
    }   
   
    public static class A<T extends A<?>> implements Copyable<T> {   
        private String a = "--A--";   
        public void copy(T t) {   
                System.out.println(t.a);   
        }   
    }   
   
    public static class B<T extends B<?>> extends A<T> {   
        private String b = "--B--";   
        public void copy(T t) {   
                super.copy(t);   
                System.out.println(t.b);   
        }   
    }   
   
    @Test   
    @SuppressWarnings("unchecked")   
    public void testCopy() {   
        Copyable b1 = new B();   
        Copyable b2 = new B();   
        b1.copy(b2);   
    }   
}


Но разобраться с предупреждениями о том что generic использован как raw type не удалось никак, кроме использования @SuppressWarnings("unchecked").

Вопрос: насколько второй вариант "идеологически" правильный и есть ли способ "честно" избавиться от предупреждений?
java generics
Re: Переопределение и generic-и
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 11.03.09 06:54
Оценка:
Здравствуйте, ojow, Вы писали:

[skipped]
Это вы автор вот этого: Overriding Java generic methods?
Re: Переопределение и generic-и
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 11.03.09 07:14
Оценка:
Здравствуйте, ojow, Вы писали:

[skipped]
Не очень кошерно, но может так?
package ru.rsdn.generics;

import org.junit.Test;

public class TestGenerics {
    public interface Copyable<T extends Copyable<? super T>> {
        void copy(T t);
    }

    public class A implements Copyable<A> {
        protected final String a = "--A--";

        public void copy(A t) {
            System.out.println(t.a);
        }
    }

    public class B extends A {
        private final String b = "--B--";

        // it's not override
        public void copy(B t) {
            super.copy(t);
            System.out.println(t.b);
        }
    }

    @Test
    public void testCopy() {
        final A a0 = new A();
        final A a1 = new A();
        a0.copy(a1);
        final A a = new A();
        final B b = new B();
        a.copy(b);
        final B b0 = new B();
        final B b1 = new B();
        b0.copy(b1);
    }
}
Re[2]: Переопределение и generic-и
От: strcpy Россия  
Дата: 11.03.09 07:23
Оценка:
R>Это вы автор вот этого:
Сам догадался или кто подсказал ?
Удвой число ошибок, если не получается добиться цели.
Re[2]: Переопределение и generic-и
От: ojow  
Дата: 11.03.09 08:08
Оценка:
Здравствуйте, rsn81.

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