Java 8 rules for method overrides:

- base class method wins against a (default) interface method,
so an abstract base class method should always be implemented
in a derived class;

- interface methods clash regardless of abstract/default
with possibly undefined behavior at run-time,
so a class or interface should always define its own method
for methods inherited from multiple interfaces and not from base class;

- meaningful diagnostics for class inheriting conflicting JVM signatures.
Since no override will happen under Java 8 rules,
ACCIDENTAL_OVERRIDE is misleading for this case;

- update testData.
This commit is contained in:
Dmitry Petrov
2015-10-07 14:43:39 +03:00
parent 82c0265cb3
commit 5d9ee7efee
46 changed files with 381 additions and 212 deletions
+3 -1
View File
@@ -9,7 +9,9 @@ interface B {
fun foo(): ArrayList<String> = ArrayList(Arrays.asList("B"))
}
open class C : A(), B
open class C : A(), B {
override fun foo(): ArrayList<String> = super<B>.foo()
}
interface D {
fun foo(): Collection<String>
@@ -1,30 +0,0 @@
interface A<T> {
fun foo(t: T): String
}
interface B {
fun foo(t: Int) = "B"
}
class Z1 : A<Int>, B
class Z2 : B, A<Int>
fun box(): String {
val z1 = Z1()
val z2 = Z2()
val z1a: A<Int> = z1
val z1b: B = z1
val z2a: A<Int> = z2
val z2b: B = z2
return when {
z1.foo( 0) != "B" -> "Fail #1"
z1a.foo( 0) != "B" -> "Fail #2"
z1b.foo( 0) != "B" -> "Fail #3"
z2.foo( 0) != "B" -> "Fail #4"
z2a.foo( 0) != "B" -> "Fail #5"
z2b.foo( 0) != "B" -> "Fail #6"
else -> "OK"
}
}
@@ -1,30 +0,0 @@
interface A<T> {
fun foo(t: T): String
}
interface B<T : Number> {
fun foo(a: T) = "B"
}
class Z1 : A<Int>, B<Int>
class Z2 : B<Int>, A<Int>
fun box(): String {
val z1 = Z1()
val z2 = Z2()
val z1a: A<Int> = z1
val z1b: B<Int> = z1
val z2a: A<Int> = z2
val z2b: B<Int> = z2
return when {
z1.foo( 0) != "B" -> "Fail #1"
z1a.foo( 0) != "B" -> "Fail #2"
z1b.foo( 0) != "B" -> "Fail #3"
z2.foo( 0) != "B" -> "Fail #4"
z2a.foo( 0) != "B" -> "Fail #5"
z2b.foo( 0) != "B" -> "Fail #6"
else -> "OK"
}
}
@@ -1,25 +0,0 @@
var result = ""
interface A {
var foo: String
get() = result
set(value) {
result += value
}
}
abstract class B {
abstract var foo: Any
}
class C : A, B()
fun box(): String {
val c = C()
c.foo = "1"
val b: B = c
val a: A = c
b.foo = "2"
a.foo = "3"
return if (result == "123") "OK" else "Fail: $result"
}
@@ -1,20 +0,0 @@
interface A {
fun foo(): String = "A"
}
interface B {
fun foo(): Any
}
class C : A, B
fun box(): String {
val c = C()
var result = ""
val b: B = c
val a: A = c
result += c.foo()
result += b.foo()
result += a.foo()
return if (result == "AAA") "OK" else "Fail: $result"
}
@@ -9,6 +9,8 @@ class B0 : Collection<String>, A0 {
override fun contains(o: String) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<String>) = throw UnsupportedOperationException()
override val size: Int
get() = super.size
}
open class A1 {
@@ -45,6 +47,8 @@ class B4 : Collection<String>, I4<Int> {
override fun contains(o: String) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<String>) = throw UnsupportedOperationException()
override val size: Int
get() = super.size
}
interface I5 : Collection<String> {
+2 -2
View File
@@ -10,8 +10,8 @@ interface B {
get() = "FAIL"
}
abstract class C {
abstract protected val c: String
open class C {
private val c: String = "FAIL"
}
open class D: C(), A, B {