4

I can make this code work without an object as input parameter for the abstract method. For example, if I make the input parameter for the printInformation() method in person and emp as printInformation(int x) it works.

The moment I make the input parameter as an object for printInformation() method as shown below, it throws an error

emp is not abstract and does not override abstract method printInformation(person) in person class emp extends person{ ^

abstract class person{
 abstract void printInformation(person p);
}

class emp extends person{
 emp(){
  System.out.println("This is a emp constructor");
 }
 void printInformation(emp e){
  System.out.println("This is an emp");
 }
}

class entity{
 public static void main(String args[]){
  emp employeeObject = new emp();
  employeeObject.printInformation(employeeObject);
 }
}
Chan
  • 2,601
  • 6
  • 28
  • 45
user547453
  • 1,035
  • 6
  • 22
  • 38
  • 1
    It's odd that `person.printInformation` requires another `person`. Shouldn't it be printing the information from the `person` instance being accessed? Also, Java convention is to start class names with an uppercase letter, e.g. `Person` and `Employee`. – David Harkness Jul 20 '12 at 02:24
  • mine is more of a concept question...i am still a newbie. Why can I override if the input parameter is not an object type? I can override it when it is of a primitive type like int... – user547453 Jul 20 '12 at 02:27

2 Answers2

4

Your interface has a function defined like this:

void printInformation(person p);

Your class has a function defined like this:

void printInformation(emp e);

Those are not the same functions. Java considers the second one a new overloaded method, not an implementation of the method from the interface. Since the class emp isn't declared abstract, but hasn't provided an implementation for the abstract method void printInformation(person), it is erroneous.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • I do not understand when you say they are not the same functions. Why can I override if the input parameter is not an object type? I can override it when it is of a primitive type like int... – user547453 Jul 20 '12 at 02:28
  • Two functions with the same name that take different arguments are `NOT` the same function. – jahroy Jul 20 '12 at 02:31
  • @jahroy....how can they be different arguments? Person is a superclass and emp is its subclass....also, you can refer a superclass variable to a subclass object. – user547453 Jul 20 '12 at 02:35
  • 2
    @user547453 - In the case of `int` you are *overloading* the method--not *overriding* it. They are indeed separate functions due to their signatures. – David Harkness Jul 20 '12 at 02:35
  • emp != person The fact that one is a subclass of the other is irrelevant in this situation. We're talking about the definition of a method, not the invocation of a method. – jahroy Jul 20 '12 at 02:40
  • 3
    @user547453: Person is a superclass and emp is the subclass, yes. And that is why they are different functions, because the types `person` and `emp` are not the same type. They are closely related, but different. To be properly implemented, you need a `printInformation` function that can take a `person` argument. You don't have one, you only have a `printInformation` function that can take an `emp`. That means someone who calls you with a `person` instance won't find an implementation they can use. – Ned Batchelder Jul 20 '12 at 02:41
  • @user547453 Jahroy hit it right on the head. When you declare a method to take a certain set of parameters in an interface, you have to implement it with exactly those parameters (assuming you're not using generics, which you are not here). As a side note, there's absolutely no reason to even take an argument to this function, since it should work on the object it's being called on. Why would you have one person print information about another person. Each person should print the information about itself. – Matt Jul 20 '12 at 02:43
  • Thanks to jahroy,Matt, Ned and David. Your answers were very valuable and I learnt well. – user547453 Jul 20 '12 at 03:40
3

I'd be doing something like this:

interface PrintsInformation<T> {
    void printInformation( T t );
}

class Emp implements PrintsInformation<Emp> {
    public void printInformation( Emp e ) {
        System.out.println( "This is an emp" );
    }
}

public static void main( String[] args ) {
    Emp employeeObject = new Emp();
    employeeObject.printInformation( employeeObject ); // compiles
}

The other way to fix your problem is to not pass in the object if it's printing itself.
Just do this:

    public void printInformation() {
        // print "this" object, rather than the one passed in
        System.out.println( "This is an emp" );
    }
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • great! but does this mean in Java I have to define an Interface to override abstract methods that take in Objects as input parameters? – user547453 Jul 20 '12 at 02:34
  • 1
    You're not overriding a method if you're implementing another method with the same name that takes different parameters... That would be called `overloading`. You can override abstract methods that take Objects as parameters... You just need to use the same parameters! – jahroy Jul 20 '12 at 02:41
  • The only way you can change the argument types and still be considered to be implementing that same interface method is using generics, as is shown in this answer. In the absence of generics, class hierarchies are not considered when determining if an interface method has been implemented. You have to be exact. That being said, since an employee is a person, any method implemented to accept a person will automatically be able to take an employee. (google the liskov substitution principle) – Matt Jul 20 '12 at 02:46