Thinking in Java (Chapter 8)
===
###### tags: `Java` `OOP`
1. Encapsulation creates new data types by combining characteristics and behaviors. Implementation hiding separates the interface from the implementation by making the details private
1. Polymorphism allows many types (derived from the same base type) to be treated as if they were one type, and a single piece of code to work on all those different types equally.
2. Connecting a method call to a method body is called binding. When binding is performed before the program is run (by the compiler and linker, if there is one), it’s called early binding
1. C compilers have only early binding method call
1. The solution is called late binding, which means that the binding occurs at run time, based on the type of object. Late binding is also called dynamic binding or runtime binding
1. All method binding in Java uses late binding unless the method is static or final (private methods are implicitly final).
1. By declaring a method final, it prevents anyone from overriding that method. Perhaps more important, it effectively “turns off” dynamic binding, or rather it tells the compiler that dynamic binding isn’t necessary. This allows the compiler to generate slightly more efficient code for final method calls
1. In a well-designed OOP program, most or all of your methods will communicate only with the base-class interface. Such a program is extensible because you can add new functionality by inheriting new data types from the common base class
1. polymorphism is an important technique for the programmer to “separate the things that change from the things that stay the same.”
2. only non-private methods may be overridden
1. only ordinary method calls can be polymorphic. For example, if you access a field directly, that access will be resolved at compile time. When a Sub object is upcast to a Super reference, any field accesses are resolved by the compiler, and are thus not polymorphic
1. In order to get the Super field you must explicitly say super.field
1. You’ll generally make all fields private and so you won’t access them directly
1. Static methods are associated with the class, and not the individual objects
1. you should perform the derived-class cleanup first, then the base-class cleanup
1. reference counting may be necessary to keep track of the number of objects that are still accessing a shared object
1. If you call a dynamically-bound method inside a constructor, the overridden definition for that method is used. However, the effect of this call can be rather unexpected because the overridden method will be called before the object is fully constructed
1. The only safe methods to call inside a constructor are those that are final in the base class(This also applies to private methods, which are automatically final.)Since a reference can be rebound to a different object at run time, a reference for a derived object can be substituted in the reference, and then the behavior changes. Thus you gain dynamic flexibility at run time. This is also called the State Pattern
1. “Use inheritance to express differences in behavior, and fields to express variations in state
1. The extended part of the interface in the derived class is not available from the base class, so once you upcast, you can’t call the new methods
1. In Java, every cast is checked! So even though it looks like you’re just performing an ordinary parenthesized cast, at run time this cast is checked to ensure that it is in fact the type you think it is. If it isn’t, you get a ClassCastException
1. Checking types at run time is called runtime type identification (RTTI)
1. If you want to access the extended interface of a derived object, you can try to downcast. If it’s the correct type, it will be successful. Otherwise, you’ll get a ClassCastException