Java-その2


Abstract class and method


A class containing abstract methods is called an abstract class.
It is possible to create a class as abstract without any abstract methods.
If a class contains one or more abstract methods, the class itself must be qualified as abstract.
Run-Time Type Identification ( RTTI )
In Java every cast is checked. If cast fails, you will get a ClassCastException. Unlike C++, cast is not ensured.
Interface
All interface elements are default public, and you can ONLY use public keywords before those elements, all the other keywords, i.e., protected, private, static, final, are illegal.
Interface can also contain fields and they are default static and final, and you can ONLY use static, final or both for the fields, all the other keywords, i.e., protected, private, are forbidden. Besides, the fields can NOT be blank finals and must be initialized at the point of definition, but they can be initialized with non-constant expressions, for example:
public interface RandVals {
    Random  mKeyGenerator = new Random();
    int mUniqueKey = mKeyGenerator.nextInt(10);
}

Inner Interface
Interfaces can be nested within classes or other interfaces. Nested interfaces can be specified aspublic, private or package access.
The private interface nested in a class can only be implemented by the inner class defined within the same class.
However, interfaces nested within another interface are default publicand can NOT be made private.
In particular, when you implement an interface, you are not required to implement any interfaces nested within.
Besides, the nested interface can have same methods as outside interface. When both the nested interface and the nesting interface are implemented in one class, the same method can only be implemented once and the implementation is for the nesting interface.
Inner class Inner classes have access rights to all the members(fields and methods) of the enclosing class and the
finalobject in the current code block.
Inner classes can also be created inside a method, which is called local inner class. A local inner class can not have an access specifier because it is not part of the outer class.
The only reason to make a local inner class rather than an anonymous inner class is if you need to make more than one object of such inner class. Inner class can also be defined within a scope inside a method, this kind of inner class is not available outside the scope in which it is defined.

The link to the outer class


No matter how deeply an inner class is nested, it can access all members of all classes it is nested within. The reason is that inner class must keep a reference to the particular object of the enclosing class that was responsible for creating it. Then when you refer to a member of the enclosing class, that hidden reference is used to select that member.
NOTE A:
Sometimes, if you need to produce the reference to the outer class object, you name the outer class followed by a dot and this. The resulting reference is automatically the correct type.
NOTE B:
Construction of the inner class object requires an object of the enclosing class, it is NOT possible to create an object of the inner class unless you already have an object of the outer class.
public class MyOuterClass {

    private int i = 0;

    class MyInnerClass {

        private int i = 1;

        public int value() { return i + MyOuterClass.this.i; }// access outer class’s member

    }

}

public static void main(String[] args) {

    MyOuterClass outerObject = new MyOuterClass();

    MyOuterClass.MyInnerClass innerObject = outerObject.newMyInnerClass();     // Must use instance of outer class to create an instances of the inner class:

}

Anonymous Inner Class Although anonymous inner classes can not have named constructors since there’s no name. But with instance initialization, you can, in effect, create a block of code, which is called initializer, to act as constructor for an anonymous inner class.
public class OutsideClass {
    public Destination dest(final String dest, final float price) {
        return new Destination() {
            private int cost;
            // Instance initialization for each object:
            {
                cost = Math.round(price);
                if(cost > 100) {
                    System.out.println("Over budget!");
                }
            private String label = dest;
            public String readLabel() { return label; }
    };
}

public static void main(String[] args) {
    OutsideClass p = new OutsideClass();
    Destination d = p.dest("Test", 10.0);
}

Above strange syntax means: “Create an object of an anonymous class that’s inherited from Destination.” The reference returned by dest( ) is automatically upcast to a Destination reference. The anonymous inner-class syntax is a shorthand for:
class MyDestination implements Destination {
    //....
}
return new MyDestination ();

From the syntax, we can see that the anonymous inner class must be created where type of base-class can be used.
Nested classes
If you do not need a connection between the inner class and the outer class, then you can make the inner classstatic. This is called a nested class. A nested class means: 1. It is no need to have an outer-class object in order to create an object of the nested class. 2. Nested class can NOT access outer-class's fields and methods unless they are static. 3. Ordinary inner classes can not have static fields, static methods, or nested classes. However, nested classes can have all of these. 4. You can not put any code inside an interface, but a nested class can be part of an interface.
Inheriting from inner class-2 B青年Because the inner class must attach to a reference of the enclosing class object.However in the derived-class inherited from the inner class, there is no default enclosing class object to attach to. So you must make the association explicitly, for example:
class Outer{
    class Inner {  }
}

public class InheritInner extends Outer.Inner {
    InheritInner(Outer outerObj) {
       outerObj.super(  );
        //…
    }
    public static void main(String[] args) {
        Outer outerObj = new Outer( );
        InheritInner iiObj = new InheritInner(outerObj);
    }
}

You can also define a new inner class inheriting from another inner class. But you must inherit the new inner class’s enclosing class from the base-inner-class’s enclosing class.
public class InheritOuter extends Outer {
    InheritOuter( )  {   }
    class InnerInheritInner extends Outer.Inner {
        InnerInheritInner( )  {   }
}

//…
public static void main(String[] args) {
    InheritOuter ioObj = new InheritOuter( );
    InheritOuter. InnerInheritInner ii = ioObj.new InnerInheritInner( );
}

}

Inner class identifiers
Since every class produces a .class file, the names of .class files for inner classes have a strict formula: the name of the enclosing class, followed by a ‘$’, followed by the name of the inner class.
If inner classes are anonymous, the compiler simply starts generating numbers as inner class identifiers.
If inner classes are nested within inner classes, their names are simply appended after a ‘$’ and the outer class identifier.   Exception
If the method definition do not have exception specification, it means that no exceptions are thrown from the method except for the exceptions inherited fromRuntimeException which can be thrown anywhere without exception specifications.
Whether or not an exception is thrown, the finally clause is always executed. Even in cases exception is not caught, finally will be executed before the exception handling mechanism continues its search for a handler at the next higher level.
The two direct subclasses of Throwable are recoverable exceptions ( Exception ) and unrecoverable errors ( Error ).

Error is the super class of all classes that represent unrecoverable errors. When errors are thrown, they should not be caught by application code. Exception is the superclass of all classes that represent recoverable exceptions. When exceptions are thrown, they may be caught by application code.
Exception Chaining Often you want to catch one exception and throw another, but still keep the information about the originating exception, this is called exception chaining. A Throwable can include a cause, which is a nested Throwable that represents the original problem that led to this Throwable. It is often used for wrapping various types of errors into a common Throwable without losing the detailed original error information. Throwable sub-classes can do it through initCause( )/getCause( ) method or constructor.
Exception Restrictions
NOTE: here we only talk about the Exception which is the superclass of all classes that represent recoverable exceptions.
As for Error, there is no restrictions, you can throw Error without any exception specification.
1. When you override a method, you can ONLY throw the exceptions that have been specified in the base-class version of the method, which means if the base-class version does NOT have any exception specification, the overridden version MUST NOT have neither. This makes sense because otherwise you’d never know if you were catching the correct thing when working with the base class.
However, the overridden version of a method can choose NOT to throw any exceptions, i.e., without any exception specification, even if the base-class version does.Overridden methods can throw inherited exceptions
すなわち、overriddenバージョンの はbase-classバージョンよりも であるか、base-classバージョンのサブセットである があります.Put another way, the “exception specification interface” for a particular method may narrow during inheritance and overriding, but it may not widen. By forcing the derived-class methods to conform to the exception specifications of the base-class methods,substitutability of objects(マルチステート)is maintained.
Besides, the overridden version can choose to declare the derived exception of the base-class's exception, this makes sense because upcast is always safe. e.g.,

class BaseException extends Exception {}
class DerivedException extends BaseException {}

abstract class Base {
    void fun() throws BaseException {
        System.out.println("Base::fun()");
    }
}

class Derived extends Base {
    void fun() throws DerivedException {
        System.out.println("Derived::fun()");
    }
}

2. The restriction on exceptions does not apply to constructors. A constructor can throw anything it wants. However, since the base-class constructor is always called,the derived-class constructor must declare all base-class constructor exceptions in its exception specification.
3. The compiler forces you to catch only the exceptions that are specific to that class, but if you upcast to the base type then the compiler (correctly) forces you to catch the exceptions for the base type. All these constraints produce much more robust exception-handling code. はコンパイル にチェックされるため、 にバインドできないため、 のclassバージョンの の と に するしかありません.
4. It’s useful to realize that although exception specifications are enforced by the compiler during inheritance, the exception specifications are not part of the type of a method, which is comprised of only the method name and argument types. Therefore, you cannot overload methods based on exception specifications. In addition, just because an exception specification exists in a base-class version of a method doesn’t mean that it must exist in the derived-class version of the method.
Exception Match
Matching an exception does not require a perfect match. A catch handler the base-exception will also catch all derived-exceptions.
NOTE: If you try to hide the derived-class exceptions by putting the base-class exception catch clause first, the compiler will give an error message, since it sees that the derived-class exception catch-clause can never be reached.