Difference between revisions of "Object Orientation"

From Suhrid.net Wiki
Jump to navigationJump to search
 
(15 intermediate revisions by the same user not shown)
Line 27: Line 27:
 
* Protected is '''wider''' than package. Protected = package + subclasses.
 
* Protected is '''wider''' than package. Protected = package + subclasses.
 
* For classes and subclasses in the same package protected works in exactly the same way as package(default).  
 
* For classes and subclasses in the same package protected works in exactly the same way as package(default).  
* For subclasses in other packages, protected members (both fields and methods) are only accessible through inheritance in the subclass.
+
* For subclasses in other packages, protected members (both fields and methods) are '''only accessible through inheritance''' in the subclass.
* The subclass in a different package cannot use a reference to super to access the protected member.
+
* The subclass in a different package cannot use a super-class reference to access the protected member.
 +
* '''Sub-class reference can be used''' to access a protected member.
 +
* The keyword '''super''' can be used to access the protected member from within a subclass.
  
 
<syntaxhighlight lang="java5">
 
<syntaxhighlight lang="java5">
Line 140: Line 142:
 
Dog d = new Dog();
 
Dog d = new Dog();
 
d.dawg();
 
d.dawg();
 +
                d.mope(); //OK subclass reference.
 
}
 
}
 
 
Line 155: Line 158:
  
 
}
 
}
 +
}
 +
 +
=== protected static methods and constructors ===
 +
 +
* Protected static methods can be invoked by all classes in the same package AND by child classes which are in other packages.
 +
* Since it is static, the rules regarding which reference (child/super) to invoke it do not apply.
 +
* It can be invoked using the Class name.
 +
* For classes in same package, invoking the protected constructor is not a problem.
 +
* FOr class outside the package, the protected constructor can only be invoked by child-classes using a call to super().
 +
 +
<syntaxhighlight lang="java5">
 +
 +
package prexams.exam4.util;
 +
 +
public class Utils {
 +
 +
protected Utils() {
 +
}
 +
 +
public Utils(String s) {
 +
}
 +
 +
protected static void do3() {
 +
System.out.println("do3");
 +
}
 +
 +
}
 +
 +
package prexams.exam4;
 +
 +
import prexams.exam4.util.Utils;
 +
 +
class NonChild {
 +
 +
public void go() {
 +
Utils u = new Utils(); //Non-child class cant access protected constructor
 +
}
 +
 +
public void bar() {
 +
Utils.do3(); // Non-child class - Protected static method is inaccessible.
 +
}
 +
}
 +
 +
public class UPS extends Utils {
 +
 +
UPS() {
 +
super(); //OK since UPS is a subclass.
 +
}
 +
 +
public static void main(String[] args) {
 +
Utils.do3(); //static is accessible
 +
UPS ups = new UPS();
 +
ups.do3(); //meaningless but OK
 +
Utils u = new Utils("u");
 +
u.do3(); //meaningless but OK
 +
}
 +
 +
public void foo() {
 +
Utils u = new Utils(); //NOT OK - UPS Constructor can only called through super().
 +
}
 +
 
}
 
}
  
Line 188: Line 252:
 
}
 
}
 
}
 
}
 +
 +
public class Override {
 +
 +
public static void main(String[] args) {
 +
Masher m = new Jaws();
 +
m.mash("Hello"); //Will print Masher.mash
 +
}
 +
 +
}
 +
 +
</syntaxhighlight>
  
 
* The return type must be the same or a subtype (Covariant return) of the superclass method.  
 
* The return type must be the same or a subtype (Covariant return) of the superclass method.  
Line 195: Line 270:
 
<syntaxhighlight lang="java5">
 
<syntaxhighlight lang="java5">
  
 +
interface Moveable {
 +
 +
Number moveIt();
 +
 +
}
 +
 +
class Bike implements Moveable {
 +
 +
public Integer moveIt() {
 +
return new Integer(42);
 +
}
 +
 +
}
 +
 +
</syntaxhighlight>
 +
 +
* Access level '''CANT be more''' restrictive but '''CAN be less''' restrictive.
  
 +
* Overriding method can throw ANY runtime exception regardless of what superclass method declares.
 +
* Overriding method cannot throw checked exceptions that are NEWER or BROADER than superclass method.
 +
* Overriding method can throw narrower or fewer checked exceptions.
 +
* It also need NOT redeclare any exceptions (checked or unchecked) from the superclass.
  
  
 +
<syntaxhighlight lang="java5">
 +
 +
class Handler {
 +
 +
public void handle() throws IOException {
 +
System.out.println("Handler.handle()");
 +
}
 +
 +
public void handleIt() throws NumberFormatException {
 +
System.out.println("Handler.handleIt()");
 +
}
 +
 +
public void handleMe() {
 +
System.out.println("Handler.handleMe()");
 +
}
 +
}
 +
 +
class FileHandler extends Handler {
 +
 +
public void handle() { //OK need not redeclare checked exception
 +
System.out.println("FileHandler.handle()");
 +
}
 +
 +
public void handleIt() { //OK need not redeclare unchecked exception
 +
System.out.println("FileHandler.handleIt()");
 +
}
 +
 +
public void handleMe() throws IllegalArgumentException { //OK can declare new unchecked exception
 +
System.out.println("Handler.handleMe()");
 +
}
 +
}
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
public class Override {
+
<syntaxhighlight lang="java5">
 +
 
 +
class Handler {
 +
 +
public void handle() throws IOException {
 +
System.out.println("Handler.handle()");
 +
}
 +
 +
public void handleIt() throws InterruptedException {
 +
System.out.println("Handler.handleIt()");
 +
}
 +
 +
public void handleMe() {
 +
System.out.println("Handler.handleMe()");
 +
}
 +
}
 +
 
 +
class FileHandler extends Handler {
 +
 +
public void handle() throws FileNotFoundException { //OK, narrower checked exception can be declared to be thrown
 +
System.out.println("FileHandler.handle()");
 +
}
 +
 +
public void handleIt() throws Exception { //NOT OK, broader checked Exception being declared
 +
System.out.println("FileHandler.handleIt()");
 +
}
 +
 +
public void handleMe() throws UnknownHostException  { //NOT OK, newer checked exception being declared
 +
System.out.println("Handler.handleMe()");
 +
}
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
=== Static Members ===
 +
 
 +
* When it comes to statics, subclasses can redefine static memebers (variables and methods). They are not overrides.
 +
* Which member will be used depends on the reference type ! not the actual object type. See below:
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
class Vehicle {
 +
 +
public static int I = 10;
 +
 +
static String stop() {
 +
return "Vehicle Stop";
 +
}
 +
 +
static String move() {
 +
return "Vehicle Move";
 +
}
 +
 +
}
 +
 
 +
class Ship extends Vehicle {
 +
 +
public static int J = 20;
 +
 +
static String move() {
 +
return "Ship Move";
 +
}
 +
 +
}
 +
 
 +
public class Statics {
 +
 
 +
public static void main(String[] args) {
 +
 +
Vehicle v = new Vehicle();
 +
 +
System.out.println(v.I);
 +
System.out.println(v.move()); //10
 +
System.out.println(v.stop()); //Vehicle Stop
 +
 +
Vehicle sv = new Ship();
 +
System.out.println(sv.I); //10
 +
System.out.println(sv.move()); //Vehicle Move
 +
 +
Ship s = new Ship(); 
 +
System.out.println(s.I);  //10
 +
System.out.println(s.J);  //20
 +
System.out.println(s.stop()); //Vehicle Stop
 +
System.out.println(s.move()); //Ship Move
 +
 
 +
}
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
* When static methods are redefined in the sub-class they dont override the superclasses's, they "hide" it.
 +
* However a '''static method CANNOT hide an instance method''' and an''' instance method CANNOT override a static method'''.
 +
 
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
class Veg {
 +
 
 +
void eat() {
 +
 +
}
 +
 +
static void grow() {
 +
 +
}
 +
}
 +
 
 +
class Potato extends Veg {
 +
 
 +
static void eat() { //COMPILER ERROR - overriding method is static
 +
 +
}
 +
 +
void grow() { //COMPILER ERROR - overriden method is static
 +
 +
}
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
== Overloading ==
 +
 
 +
* Overloaded methods differ only in argument list, no other restrictions.
 +
* Methods can be overloaded with argument types that are in the same hierarchy.
 +
* '''The decision to invoke a particular overloaded method is made at COMPILE time''', not at RUN time like polymorphic methods.
 +
* See below: compiler will invoke overloaded method depending on the reference type.
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
class Gadget {
 +
}
 +
 
 +
class Phone extends Gadget {
 +
}
 +
 
 +
public class Overlord {
  
 
public static void main(String[] args) {
 
public static void main(String[] args) {
Masher m = new Jaws();
+
new Overlord().go();
m.mash("Hello"); //Will print Masher.mash
+
}
 +
 +
void go() {
 +
Gadget g = new Gadget();
 +
Phone p = new Phone();
 +
Gadget gp = new Phone();
 +
 +
foo(g); //Prints: Gadget
 +
foo(p); //Prints: Phone
 +
foo(gp);//Prints: Gadget
 +
 +
}
 +
 +
void foo(Gadget g) {
 +
System.out.println("Gadget");
 
}
 
}
 
 
 +
void foo(Phone p) {
 +
System.out.println("Phone");
 +
}
 +
 
}
 
}
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
== Casting ==
  
 +
* References can be cast if the types belong in the same hierarchy.
 +
* This means that an Object reference can be cast to anything.... because everything is an Object.
 +
* However, the compiler can figure out if two references are of completely different types and they cannot be cast
 +
 +
<syntaxhighlight lang="java5">
 +
 +
                Object obj = new String();
 +
String str = (String) obj;          //OK, an object can be a String.
 +
 +
                Object obj2 = new Integer();
 +
                String str2 = (String) obj2; //Compiler says OK - but this will fail at runtime with a ClassCastException
 +
 +
Exception oie = new InterruptedException();
 +
OutOfMemoryError ome = (OutOfMemoryError) oie;    //An Exception can never be an Error
 +
 +
 +
</syntaxhighlight>
 +
 +
* The cast need not be of the same type as that of the reference variable, it can be of a sub-type as well:
 +
 +
<syntaxhighlight lang="java5">
 +
 +
interface Computable {
 +
}
 +
 +
class Electronics {
 +
}
 +
 +
class Computer extends Electronics implements Computable {
 +
}
 +
 +
class Laptop extends Computer {
 +
}
 +
 +
public class Casting {
 +
 +
public static void main(String[] args) {
 +
 +
Electronics e = new Laptop();
 +
 +
Electronics e2 = (Computer) e;
 +
 +
Computer comp = (Laptop) e;
 +
 +
}
 +
}
 +
 +
</syntaxhighlight>
  
  
 
[[Category:OCPJP]]
 
[[Category:OCPJP]]

Latest revision as of 05:34, 13 September 2011

Constructors

  • NO return type.
  • Can have all the access modifiers.
  • Can't be marked as abstract or final or static.

Class Modifiers

Regular Classes:

  • Access Modifiers: public and default only
  • Non access: strictfp, abstract and final only
  • Adding any other modifier will result in a compiler error.
  • A final class cannot be overriden (e.g. String)
  • An abstract class cannot be instantiated (e.g. DateFormat)

Class Members

  • Members can use all the access modifiers: public, private, default(package), protected
  • Private members are not inherited.
  • This means private members can be redeclared in subclasses.
  • Instance level variables cannot be synchronized, abstract, strictfp, native.

Protected

  • Protected is wider than package. Protected = package + subclasses.
  • For classes and subclasses in the same package protected works in exactly the same way as package(default).
  • For subclasses in other packages, protected members (both fields and methods) are only accessible through inheritance in the subclass.
  • The subclass in a different package cannot use a super-class reference to access the protected member.
  • Sub-class reference can be used to access a protected member.
  • The keyword super can be used to access the protected member from within a subclass.
package pkg1;

public class Foo {
  protected String str = "Hello";
}

package pkg2;

public class Bar extends Foo {
  public void go() {
     Foo f = new Foo();
     String s = f.str; //Wont work ! Compiler error
     System.out.println(str); //Will work - through inheritance
  }
}

package pkg2;

public class Fubar {
   public void goo() {
        Bar b = new Bar();
        System.out.println(b.str); //wont work - str only accessible through inheritance
   }
}
  • One more example
package pkgA;

public class Animal {
	
	int count = 10;
	protected int secret = 42;
	
	void eat() {
		System.out.println("Animal Eat");
	}
	
	protected void mope() {
		System.out.println("Animal Moping");
	}
	
}

//Same package - different class

package pkgA;

public class Zoo {

	public static void main(String[] args) {
		Zoo z = new Zoo();
		z.go();
	}
	
	public void go() {
		Animal a = new Animal();
                //Package and protected are accessible
		a.eat();
		a.mope();
		System.out.printf("Package : %d %n", a.count);
		System.out.printf("Protected : %d %n", a.secret);
	}

}

//Same package - subclass

package pkgA;

public class Cat extends Animal {
	
	public static void main(String[] args) {
		Cat c = new Cat();
		c.catnap();
	}
	
	public void catnap() {
		System.out.println("Animal count :" + count); //package variable through inheritance
		System.out.println("Secret : " + secret); //protected variable through inheritance
                eat(); //package method through inheritance
		mope(); //protected method through inheritance

                Animal a = new Animal();
                //Access through super-class reference or super in all cases will work.
                a.count = 20;      
                super.secret = 18;
                super.eat();  
                a.mope(); 
	}
}


//Subclass in a different package

package pkgB;

import pkgA.Animal;

public class Dog extends Animal {

	public static void main(String[] args) {
		Dog d = new Dog();
		d.dawg();
                d.mope(); //OK subclass reference.
	}
	
	public void dawg() {
                //None of the package level members will be accessible.

		System.out.println(secret); //This will work
                System.out.println(super.secret) // OR this will too
                Animal a = new Animal();
                System.out.println(a.secret); //This wont. Compile error.
                
                System.out.println(mope()); //OK
                System.out.println(super.mope()); //OK
                System.out.println(a.mope()); //NO. Compiler error.

	}
}

=== protected static methods and constructors ===

* Protected static methods can be invoked by all classes in the same package AND by child classes which are in other packages.
* Since it is static, the rules regarding which reference (child/super) to invoke it do not apply.
* It can be invoked using the Class name.
* For classes in same package, invoking the protected constructor is not a problem.
* FOr class outside the package, the protected constructor can only be invoked by child-classes using a call to super().

<syntaxhighlight lang="java5">

package prexams.exam4.util;

public class Utils {
	
	protected Utils() {
	}
	
	public Utils(String s) {
	}
	
	protected static void do3() {
		System.out.println("do3");
	}

}

package prexams.exam4;

import prexams.exam4.util.Utils;

class NonChild {
	
	public void go() {
		Utils u = new Utils(); //Non-child class cant access protected constructor
	}
	
	public void bar() {
		Utils.do3(); // Non-child class - Protected static method is inaccessible.
	}
}

public class UPS extends Utils {
	
	UPS() {
		super(); //OK since UPS is a subclass.
	}
	
	public static void main(String[] args) {
		Utils.do3(); //static is accessible
		UPS ups = new UPS();
		ups.do3(); //meaningless but OK
		Utils u = new Utils("u");
		u.do3(); //meaningless but OK
	}
	
	public void foo() {
		Utils u = new Utils(); //NOT OK - UPS Constructor can only called through super().
	}

}

Abstract Methods

As they go against the logic of overriding :

  • abstract methods cannot be static.
  • abstract methods cannot be private.

Overriding

  • Polymorphic method invocations apply ONLY to instance methods.
  • The argument list for the overriding method must EXACTLY match that of the overriden method. Covariant arguments wont work! If arguments dont match, then the methods will overload.
  • Example:
class Masher {
	
	public void mash(Object o) {
		System.out.println("Masher.mash");
	}
	
}

class Jaws extends Masher {
	
	public void mash(String o) { //Overloads not Overrides the superclass method
		System.out.println("Jaws.mash");
	}
}

public class Override {

	public static void main(String[] args) {
		Masher m = new Jaws();
		m.mash("Hello"); //Will print Masher.mash
	}
	
}
  • The return type must be the same or a subtype (Covariant return) of the superclass method.
  • If the return types are not the same and arguments are the same - then this will be a name clash and the code wont compile.
  • Example:
interface Moveable {
	
	Number moveIt();
	
}

class Bike implements Moveable {
	
	public Integer moveIt() {
		return new Integer(42);
	}
	
}
  • Access level CANT be more restrictive but CAN be less restrictive.
  • Overriding method can throw ANY runtime exception regardless of what superclass method declares.
  • Overriding method cannot throw checked exceptions that are NEWER or BROADER than superclass method.
  • Overriding method can throw narrower or fewer checked exceptions.
  • It also need NOT redeclare any exceptions (checked or unchecked) from the superclass.


class Handler {
	
	public void handle() throws IOException {
		System.out.println("Handler.handle()");
	}
	
	public void handleIt() throws NumberFormatException {
		System.out.println("Handler.handleIt()");
	}
	
	public void handleMe() {
		System.out.println("Handler.handleMe()");
	}
}

class FileHandler extends Handler {
	
	public void handle() { //OK need not redeclare checked exception
		System.out.println("FileHandler.handle()");
	}
	
	public void handleIt() { //OK need not redeclare unchecked exception
		System.out.println("FileHandler.handleIt()");
	}
	
	public void handleMe() throws IllegalArgumentException { //OK can declare new unchecked exception
		System.out.println("Handler.handleMe()");
	}
}


class Handler {
	
	public void handle() throws IOException {
		System.out.println("Handler.handle()");
	}
	
	public void handleIt() throws InterruptedException {
		System.out.println("Handler.handleIt()");
	}
	
	public void handleMe() {
		System.out.println("Handler.handleMe()");
	}
}

class FileHandler extends Handler {
	
	public void handle() throws FileNotFoundException { //OK, narrower checked exception can be declared to be thrown
		System.out.println("FileHandler.handle()");
	}
	
	public void handleIt() throws Exception { //NOT OK, broader checked Exception being declared
		System.out.println("FileHandler.handleIt()");
	}
	
	public void handleMe() throws UnknownHostException  { //NOT OK, newer checked exception being declared
		System.out.println("Handler.handleMe()");
	}
}

Static Members

  • When it comes to statics, subclasses can redefine static memebers (variables and methods). They are not overrides.
  • Which member will be used depends on the reference type ! not the actual object type. See below:
class Vehicle {
	
	public static int I = 10;
	
	static String stop() {
		return "Vehicle Stop";
	}
	
	static String move() {
		return "Vehicle Move";
	}
	
}

class Ship extends Vehicle {
	
	public static int J = 20;
	
	static String move() {
		return "Ship Move";
	}
	
}

public class Statics {

	public static void main(String[] args) {
		
		Vehicle v = new Vehicle();
		
		System.out.println(v.I);
		System.out.println(v.move()); //10
		System.out.println(v.stop()); //Vehicle Stop
		
		Vehicle sv = new Ship();
		System.out.println(sv.I); //10
		System.out.println(sv.move()); //Vehicle Move
	
		Ship s = new Ship();   
		System.out.println(s.I);  //10
		System.out.println(s.J);  //20
		System.out.println(s.stop()); //Vehicle Stop
		System.out.println(s.move()); //Ship Move

	}
}


  • When static methods are redefined in the sub-class they dont override the superclasses's, they "hide" it.
  • However a static method CANNOT hide an instance method and an instance method CANNOT override a static method.


class Veg {

	void eat() {
		
	}
	
	static void grow() {
		
	}
}

class Potato extends Veg {

	static void eat() { //COMPILER ERROR - overriding method is static
		
	}
	
	void grow() { //COMPILER ERROR - overriden method is static
		
	}
}

Overloading

  • Overloaded methods differ only in argument list, no other restrictions.
  • Methods can be overloaded with argument types that are in the same hierarchy.
  • The decision to invoke a particular overloaded method is made at COMPILE time, not at RUN time like polymorphic methods.
  • See below: compiler will invoke overloaded method depending on the reference type.
class Gadget {
}

class Phone extends Gadget {
}

public class Overlord {

	public static void main(String[] args) {
		new Overlord().go();
	}
	
	void go() {
		Gadget g = new Gadget();
		Phone p = new Phone();
		Gadget gp = new Phone();
		
		foo(g); //Prints: Gadget
		foo(p); //Prints: Phone
		foo(gp);//Prints: Gadget
		
	}
	
	void foo(Gadget g) {
		System.out.println("Gadget");
	}
	
	void foo(Phone p) {
		System.out.println("Phone");
	}

}

Casting

  • References can be cast if the types belong in the same hierarchy.
  • This means that an Object reference can be cast to anything.... because everything is an Object.
  • However, the compiler can figure out if two references are of completely different types and they cannot be cast
                Object obj = new String();
		String str = (String) obj;          //OK, an object can be a String.

                Object obj2 = new Integer();
                String str2 = (String) obj2; //Compiler says OK - but this will fail at runtime with a ClassCastException
		
		Exception oie = new InterruptedException();
		OutOfMemoryError ome = (OutOfMemoryError) oie;     //An Exception can never be an Error
  • The cast need not be of the same type as that of the reference variable, it can be of a sub-type as well:
interface Computable {
}

class Electronics {
}

class Computer extends Electronics implements Computable {
}

class Laptop extends Computer {
}

public class Casting {

	public static void main(String[] args) {
		
		Electronics e = new Laptop();
		
		Electronics e2 = (Computer) e;
		
		Computer comp = (Laptop) e;
		
	}
}