2016-11-17 3 views
2

У меня есть абстрактный класс в библиотеке я хотел реализовать в Scala, который имеет абстрактный метод копирования с ограниченными наследованиями следующим образом:Перекрытие абстрактного метода класса Java в Scala с ограниченным наследованием

// Java code 
public abstract class Base { 
     public abstract <T extends Base> T copy(); 
} 

Когда я создаю класс в Java это работает отлично, т.е.

public class FromBase extends Base { 
    @Override 
    @SuppressWarnings("unchecked") 
    public FromBase copy(); 
} 

Но если я попытаюсь сделать это в Scala ниже дает method 'copy' overrides nothing:

class FromBase extends Base { 
    override def copy(): FromBase = new FromBase() 
} 

И ниже IDE-предложил работает, но требует вызова с типом v.copy[FromBase]() работой:

class FromBase extends Base { 
    override def copy[T <: Tuple](): T = (new FromBase).asInstanceOf[T] 
} 

Поскольку метод может быть вызван из Java, мне нужна копия без родового работать, как в примере Java.

+1

Есть что-то странное: базовому классу требуется, чтобы метод копирования возвращал некоторый подтип самого базового класса, а последний фрагмент вводит класс кортежа. Это просто опечатка? – stefanobaghino

+0

Да, это опечатка; Я просто упростил существующую проблему, которая, например, работает с классами Tuple. –

ответ

2

В заявлении Base.copy говорится, что он может вернуть независимо от подтипа Base его спрашивают. Это полностью действует написать

Base base = new FromBase; 
AnotherBaseSubclass base2 = base.copy(); 
// same as AnotherBaseSubclass base2 = base.<AnotherBaseSubclass>copy(); 

Это, очевидно, не может работать, если FromBase.copy фактический тип возвращаемого значения FromBase. Таким образом, «предупреждение», которое вы подавляете, должно быть ошибкой, и Scala не позволяет этого.

Возможно, вам действительно понадобится T по телефону Base, а не copy. Если вы исправите это:

// Java code 
public abstract class Base<T extends Base> { 
     public abstract T copy(); 
} 

// Scala 
class FromBase extends Base[FromBase] { 
    override def copy() = new FromBase 
} 

он будет компилировать и не требовать каких-либо бросков или подавленных предупреждений.

+0

Благодарим вас за подробное объяснение. Чтобы уточнить, если метод определен выше, нет допустимого способа перегрузить его в Scala, правильно? Проблема в этом случае заключается в том, что базовый метод является частью библиотеки, и я не могу изменить способ его определения. –

+0

Также нет действительного способа реализации Java. Наиболее близким к действительным способом в Scala является предложенная IDE, которую вы даете в вопросе. Не требуется указывать параметр типа, если ожидаемый тип известен, как и в Java: 'val base2: FromBase = v.copy()'. –

+0

Но, если вы не упростили слишком много, этот проект настоятельно предлагает авторам библиотеки не понимать дженерики, и его не следует использовать (по крайней мере, не обертывая его более разумным API). –

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