tcltest::test 8.1.1.1-1 { declare an abstract class } {
    compile [saveas T8111_1.java "abstract class T8111_1 {}"]
} PASS

tcltest::test 8.1.1.1-2 { Compile time error on attempt to create an instance
        of an abstract class, even if it has no abstract methods } {
    compile [saveas T8111_2.java {
abstract class T8111_2 {
    Object o = new T8111_2();
}
    }]
} FAIL

# These next two could also be covered in 8.4.3.1 (abstract methods)

tcltest::test 8.1.1.1-3 { declare an abstract class with an abstract method } {
    compile [saveas T8111_3.java {
abstract class T8111_3 {
    abstract void foo();
}
    }]
} PASS

tcltest::test 8.1.1.1-4 { a non-abstract class can not have an abstract
        method } {
    empty_class T8111_4 {
	abstract void foo();
    }
} FAIL

tcltest::test 8.1.1.1-5 { An attempt to inherit from an abstract superclass
        containing an abstract method without implementing the abstract method
        or declaring the subclass abstract is a compile time error } {
    compile [saveas T8111_5a.java {
abstract class T8111_5a {
    abstract void foo();
}
class T8111_5b extends T8111_5a {}
    }]
} FAIL

tcltest::test 8.1.1.1-6 { An attempt to inherit from an abstract superclass that
        extends another class that has an abstract method without implementing
        the abstract method or declaring the subclass abstract should generate
        a compile time error } {
    compile [saveas T8111_6a.java {
abstract class T8111_6a {
    abstract void foo();
}
abstract class T8111_6b extends T8111_6a {}
class T8111_6c extends T8111_6b {}
    }]
} FAIL

tcltest::test 8.1.1.1-7 { inherit from an abstract class with an
        abstract method, the subclass must be marked as abstract } {
    compile [saveas T8111_7a.java {
abstract class T8111_7a {
    abstract void foo();
}
abstract class T8111_7b extends T8111_7a {}
    }]
} PASS

tcltest::test 8.1.1.1-8 { Compile time error on attempt to create an instance
        of an abstract class that inherits from and abstract class } {
    compile [saveas T8111_8.java {
abstract class T8111_8 {
    abstract void foo();
    Object o = new T8111_8();
}
    }]
} FAIL

tcltest::test 8.1.1.1-9 { It should be possible to inherit from an abstract
        class that defines no abstract methods, the subclass does not need to
        be abstract } {
    compile [saveas T8111_9a.java {
abstract class T8111_9a {}
class T8111_9b extends T8111_9a {}
    }]
} PASS

tcltest::test 8.1.1.1-10 { Inherit from an abstract class with no methods that
        also inherits from an abstract class with no methods, subclass does not
        need to be abstract } {
    compile [saveas T8111_10a.java {
abstract class T8111_10a {}
abstract class T8111_10b extends T8111_10a {}
class T8111_10c extends T8111_10b {}
    }]
} PASS

tcltest::test 8.1.1.1-11 { Implement an abstract method inherited from an
        abstract superclass } {
  compile [saveas T8111_11a.java {
abstract class T8111_11a {
    abstract void foo();
}
abstract class T8111_11b extends T8111_11a {}
class T8111_11c extends T8111_11b {
    void foo() {}
}
    }]
} PASS

# This next one is mentioned in 8.1.1.1, but is also covered by the return
# type conflict rules of 8.4.

tcltest::test 8.1.1.1-12 { A compile time error should be generated when an
        abstract class has two methods with the same signature but different
        return types, this would create an abstract class that could not be
        sub-classed } {
    compile [saveas T8111_12a.java {
interface T8111_12a {
    void foo();
}
abstract class T8111_12b implements T8111_12a {
    public abstract int foo();
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-1 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da1a.java {
package p1;
public abstract class T8111da1a {
  abstract void m();
}
    }] [saveas T8111da1b.java {
class T8111da1b extends p1.T8111da1a {}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-2 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da2a.java {
package p1;
public abstract class T8111da2a {
  abstract void m();
}
    }] [saveas T8111da2b.java {
abstract class T8111da2b extends p1.T8111da2a {}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-3 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da3a.java {
package p1;
public abstract class T8111da3a {
  abstract void m();
}
    }] [saveas T8111da3b.java {
abstract class T8111da3b extends p1.T8111da3a {}
class T8111da3c extends T8111da3b {}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-4 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da4a.java {
package p1;
public abstract class T8111da4a {
  abstract void m();
}
    }] [saveas T8111da4b.java {
abstract class T8111da4b extends p1.T8111da4a {}
abstract class T8111da4c extends T8111da4b {}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-5 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da5a.java {
package p1;
public abstract class T8111da5a {
  abstract void m();
}
    }] [saveas p2/T8111da5b.java {
package p2;
public abstract class T8111da5b extends p1.T8111da5a {}
    }] [saveas p1/T8111da5c.java {
package p1;
public class T8111da5c extends p2.T8111da5b {}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-6 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da6a.java {
package p1;
public abstract class T8111da6a {
  abstract void m();
}
    }] [saveas p2/T8111da6b.java {
package p2;
public abstract class T8111da6b extends p1.T8111da6a {}
    }] [saveas p1/T8111da6c.java {
package p1;
public abstract class T8111da6c extends p2.T8111da6b {}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-7 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da7b.java {
package p1;
abstract class T8111da7a {
  abstract void m();
}
public abstract class T8111da7b extends T8111da7a {}
    }] [saveas T8111da7c.java {
abstract class T8111da7c extends p1.T8111da7b {}
class T8111da7d extends T8111da7c {}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-8 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da8b.java {
package p1;
abstract class T8111da8a {
  abstract void m();
}
public abstract class T8111da8b extends T8111da8a {}
    }] [saveas T8111da8c.java {
abstract class T8111da8c extends p1.T8111da8b {}
abstract class T8111da8d extends T8111da8c {}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-9 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da9a.java {
package p1;
public abstract class T8111da9a {
  abstract void m();
}
    }] [saveas p2/T8111da9b.java {
package p2;
public abstract class T8111da9b extends p1.T8111da9a {}
class T8111da9d extends p1.T8111da9c {}
    }] [saveas p1/T8111da9c.java {
package p1;
public abstract class T8111da9c extends p2.T8111da9b {
    void m() {} // overrides a.m(), even though a.m() is not inherited!
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-10 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da10a.java {
package p1;
public abstract class T8111da10a {
    abstract void m();
}
class T8111da10c extends p2.T8111da10b {
    void m() {} // overrides a.m(), even though a.m() is not inherited!
}
    }] [saveas p2/T8111da10b.java {
package p2;
public abstract class T8111da10b extends p1.T8111da10a {}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-11 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    ok_pass_or_warn [compile [saveas p1/T8111da11a.java {
package p1;
public abstract class T8111da11a {
    abstract void m();
}
    }] [saveas T8111da11b.java {
abstract class T8111da11b extends p1.T8111da11a {
    // b.m() does not implement a.m(), since it is not accessible; no concrete
    // subclass of b can exist (either it would be out of p1, and still not
    // implement a.m(), or it would be in p1, and cannot override a.m and b.m
    // simultaneously)
    protected int m() { return 1; }
}
    }]]
} OK

tcltest::test 8.1.1.1-default-abstract-12 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    ok_pass_or_warn [compile [saveas p1/T8111da12a.java {
package p1;
public abstract class T8111da12a {
    abstract void m();
}
    }] [saveas T8111da12b.java {
interface T8111da12b {
    int m();
}
abstract class T8111da12c extends p1.T8111da12a implements T8111da12b {
    // c is legal: since a.m is not inherited, there are no conflicting
    // signatures. However, no concrete subclass of c can exist (either it
    // would be out of p1, and not implement a.m(), or it would be in p1, and
    // cannot override a.m and b.m simultaneously)
}
    }]]
} OK

tcltest::test 8.1.1.1-default-abstract-13 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da13a.java {
package p1;
public class T8111da13a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m();
    }
}
    }] [saveas T8111da13b.java {
class T8111da13b extends p1.T8111da13a {
    class D extends C implements I {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and D must be abstract
	public void m() {}
    }
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-14 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da14a.java {
package p1;
public class T8111da14a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m();
    }
}
    }] [saveas T8111da14b.java {
class T8111da14b extends p1.T8111da14a {
    abstract class D extends C implements I {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and D must be abstract
	public void m() {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-15 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da15a.java {
package p1;
public class T8111da15a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m();
    }
}
    }] [saveas T8111da15b.java {
class T8111da15b extends p1.T8111da15a {
    abstract class D extends C implements I {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and E must be abstract
	public void m() {}
    }
    class E extends D {}
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-16 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da16a.java {
package p1;
public class T8111da16a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m() throws Exception;
    }
}
    }] [saveas T8111da16b.java {
class T8111da16b extends p1.T8111da16a {
    abstract class D extends C implements I {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-17 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da17a.java {
package p1;
public class T8111da17a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m() throws Exception;
    }
}
class T8111da17c extends p2.T8111da17b {
    class E extends D {
	// This overrides and implements C.m (even though B.m was not inherited)
	// so it cannot throw
	public void m() throws Exception {}
    }
}
    }] [saveas p2/T8111da17b.java {
package p2;
public class T8111da17b extends p1.T8111da17a {
    abstract class D extends C implements I {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-18 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da18a.java {
package p1;
public class T8111da18a {
    public abstract class C {
	abstract void m();
    }
    public interface I {
	void m() throws Exception;
    }
}
class T8111da18c extends p2.T8111da18b {
    class E extends D {
	// This overrides and implements C.m (even though B.m was not inherited)
	// so it cannot throw
	public void m() {}
    }
}
    }] [saveas p2/T8111da18b.java {
package p2;
public class T8111da18b extends p1.T8111da18a {
    public abstract class D extends C implements I {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-19 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da19a.java {
package p1;
public class T8111da19a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m();
    }
    protected abstract class C1 extends C implements I {}
}
    }] [saveas T8111da19b.java {
class T8111da19b extends p1.T8111da19a {
    class D extends C1 {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and D must be abstract
	public void m() {}
    }
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-20 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da20a.java {
package p1;
public class T8111da20a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m();
    }
    protected abstract class C1 extends C implements I {}
}
    }] [saveas T8111da20b.java {
class T8111da20b extends p1.T8111da20a {
    abstract class D extends C1 {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and D must be abstract
	public void m() {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-21 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da21a.java {
package p1;
public class T8111da21a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m();
    }
    protected abstract class C1 extends C implements I {}
}
    }] [saveas T8111da21b.java {
class T8111da21b extends p1.T8111da21a {
    abstract class D extends C1 {
	// this implements I.m, but not C.m, since that was not accessible
	// therefore, C.m remains unimplemented, and E must be abstract
	public void m() {}
    }
    class E extends D {}
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-22 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da22a.java {
package p1;
public class T8111da22a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m() throws Exception;
    }
    protected abstract class C1 extends C implements I {}
}
    }] [saveas T8111da22b.java {
class T8111da22b extends p1.T8111da22a {
    abstract class D extends C1 {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-23 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da23a.java {
package p1;
public class T8111da23a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m() throws Exception;
    }
    protected abstract class C1 extends C implements I {}
}
class T8111da23c extends p2.T8111da23b {
    class E extends D {
	// This overrides and implements C.m (even though B.m was not inherited)
	// so it cannot throw
	public void m() throws Exception {}
    }
}
    }] [saveas p2/T8111da23b.java {
package p2;
public class T8111da23b extends p1.T8111da23a {
    abstract class D extends C1 {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} FAIL

tcltest::test 8.1.1.1-default-abstract-24 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da24a.java {
package p1;
public class T8111da24a {
    abstract class C {
	abstract void m();
    }
    interface I {
	void m() throws Exception;
    }
    protected abstract class C1 extends C implements I {}
}
class T8111da24c extends p2.T8111da24b {
    class E extends D {
	// This overrides and implements C.m (even though B.m was not inherited)
	// so it cannot throw
	public void m() {}
    }
}
    }] [saveas p2/T8111da24b.java {
package p2;
public class T8111da24b extends p1.T8111da24a {
    public abstract class D extends C1 {
	// since C.m is not accessible, this only implements I.m, and hence can
	// throw. However, since C.m remains unimplemented, a concrete subclass
	// will have to override D.m and lose the throws clause
	public void m() throws Exception {}
    }
}
    }]
} PASS

tcltest::test 8.1.1.1-default-abstract-25 { Default access abstract methods are
        not inherited across class boundaries, but do affect whether the
        class must be abstract } {
    compile [saveas p1/T8111da25a.java {
package p1;
public abstract class T8111da25a {
    abstract void m();
}
    }] [saveas p2/T8111da25b.java {
package p2;
public abstract class T8111da25b extends p1.T8111da25a {
    // the change in signature is legal, since a.m is not inherited
    abstract int m() throws Exception;
}
class T8111da25d extends p1.T8111da25c {
    // With the implementation of b.m, there are no abstract methods in d
    int m() throws Exception { return 1; }
}
    }] [saveas p1/T8111da25c.java {
package p1;
public abstract class T8111da25c extends p2.T8111da25b {
    // this class must be abstract, even though it implements a.m
    void m() {} // overrides the non-inherited a.m!
}
    }]
} PASS

