1

I am familiar with type casting in inheritance model.

Let SuperClass and SubClass be parent and child classes;

SuperClass superClass = new SubClass(); -- Here the object instantiated is a subclass object; but its reference type is SuperClass; that is only those methods of SuperClass can be called on the subclass object; Any methods that are not inherited/overridden in subclass cannot be called (that is any unique methods of subclass).

I observed same behavior as above if SuperClass is an interface and SubClass implements it. That is only those methods declared in SuperClass interface are available to be called on the SubClass object. Is my understanding correct? But with some casting, I can call methods that is not part of the interface, which I have observed in my sample code below;

I have made some comments on my understanding as how it works; but I would like to know if that make sense or if my interpretation is wrong;

class Animals {

     public void bark(){
         System.out.println("animal is barking");
     }

}

 interface catIF {
     public void catting();

 }

interface dogIF {
    public void dogging();
 }

class Dog extends Animals implements dogIF {

    public void bark(){
        System.out.println("dog is barking");
    }


    public void dogging() {
        System.out.println("dogging");

    }

}

class Cat extends Animals implements catIF {

    public void bark(){
        System.out.println("cat is barking");
    }


    public void catting() {
        System.out.println("catting");

    }

}

public class Animal {

    public static void main(String[] args){
        dogIF dog = new Dog();
        //dog.bark(); this fails
        //This method actually actually exists;
        //but it is not available or hidden because dogIF reference
        //limits its availability; (this is similar to inheritance)

        Dog dog2 = new Dog();
        dog2.bark();
        ////prints dog is barking

        Animals an =(Animals) dog;
        an.bark();
        //prints dog is barking
        //by casting we mean, treat the dog as an animals reference
        //but the object itself is a dog.
        //call the bark() method of dog
        //but dog did not have this method in the beginning (see first line
        // in main - when instantiated with interface type)
        }
     }
7
  • dogIF#bark() does not exist, so you are right about that. Method invocations are resolved, at compile time, based on the declared type of the reference. Commented Feb 4, 2014 at 19:11
  • Yes your understand is perfectly fine. Commented Feb 4, 2014 at 19:12
  • Inheritance if interfaces is a little flaky in Java -- I'm not sure anyone really understands it. (I understood it long enough to implement checkcast, but the rules are so arcane I've long since forgotten them.) Commented Feb 4, 2014 at 19:19
  • But one thing to understand is that when you do an explicit cast ((Animals), eg) then the compiler takes your word for it that the object in question is the type specified. Under the covers a checkcast bytecode assures that what you say is true, but the compiler has no idea whether the checkcast will succeed or fail. Commented Feb 4, 2014 at 19:23
  • 1
    Casts check whether the object implements the new type before they take effect, and throw a ClassCastException if it doesn't. So, either Cat or Dog extends/implements Animals and can be cast to Animals, but they don't have a super/subclass relationship to each other so you can't cast one to the other. Although you could have an object which extended Cat and implemented dogIF, if you wanted to describe a cat that shared the latter behavior with dogs... like mine, which will sometimes retrieve a ball. Commented Feb 4, 2014 at 19:39

1 Answer 1

4

Inheritance of interfaces really isn't "flaky" or complicated. They behave exactly the way abstract classes do, with the exceptions that you reference them differently (implements rather than extends) and that you're allowed to inherit as many interfaces as you like but can only have one superclass (abstract or not).

As with other inheritance: If all you know about an object is that it implements an interface, then you can only access it through that interface. If you know that it implements another interface, or a specific superclass, or is an instance of a particular class, then you can cast it to those and access it through the exposed members of those.

So, yes: If all your program knows is that the object is an instance of Animals, then all you can do is call what's declared on Animals. That means bark() plus whatever methods it inherits from Object (since everything is an Object directly or indirectly even if that isn't explicitly stated).

If your program knows that the object is an implementation of dogIF or catIF -- because the variable type says it is, or because you've successfully typecast it to one of those interfaces -- you can also call the method(s) declared by those interfaces. By the way, the usual convention for interfaces is to name them like classes, with UppercasedFirstLetter... since in many cases the difference between an interface and a class really isn't significant to the folks using it.

If your program happens to know that the object is a Dog, you can call anything it inherits from either Animals or dogIF, or that is provided directly by Dog. Of course it could actually be a Chihuahua (subclass of dog), but that's OK, the subclass will respond to anything the superclass would have responded to, in "the right way to maintain the semantics". (That is, a Chihuahua may respond to bark() by saying "yip yip yip grr yip!", but that method really shouldn't cause it to try to bite your ankle.)

Hope that helps. It really isn't that complicated.

Sign up to request clarification or add additional context in comments.

9 Comments

is variable type same as reference type? and regarding your sentence If your program happens to know that the object is a Dog, you can call anything it inherits from either Animals or dogIF, or that is provided directly by Dog -- possible only when I declare Dog dog = new Dog(); but not Animals dog = new Dog() or dogIF dog = new Dog()
1) All object variables in Java are references, so yes. (As opposed to the object's actual type.) (2) If you know the object is a Dog -- either because you created it, or because you know that from other context, or because you've just used the instanceof operation to check this -- you can safely typecast it to Dog and treat it as such. I admit I shorthanded that a bit.
consider this: dogIF dog = new Dog(); The object is a Dog object; but this is not allowed: (Dog)dog.bark(). I guess I have some misunderstanding here..
There's no guarantee that an arbitrary dogIF can be cast to Dog -- but that just means that the cast will throw ClassCastException if the object isn't an instance of what it's being cast to. If it is an instance of Dog, there's nothing wrong with the typecast... though you may need to be careful to make sure that you're casting the object rather than the result. Try ((Dog)dog).bark().
You didn't have to write the code behind checkcast ... and get it to pass the Sun acceptance test. There are several non-obvious twists and turns.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.