0

If we have for example :

class Person {
  // public void printInfos(){ }
}

class Student extends Person {
     public void printInfos(){
          System.out.println("studentInfos");
     }
}

class Teacher extends Person(){
     public void printInfos(){
          System.out.println("teacherInfos");
     }
}

main:
Person p1 = new Student();
Person p2 = new Teacher();

I want to write : p1.printInfos() and p2.printInfos() and print "studentInfos" & "teacherInfos" but I can't find a solution other than declaring an empty method inside the class Person (since we can't declare it as abstract and override it otherwise there will be no instanciation possible). I feel that the declaration of an empty method is wrong even if it works.

Spn
  • 410
  • 2
  • 7
  • 16
  • 1
    I'm not sure why you don't want to make it abstract. If your Person was abstract then your code would still run as is, you simply can't use "new Person()" if Person is abstract. Second, you probably do want an empty method, or maybe one which throws an exception if called and then override it in the base classes. https://www.jitendrazaa.com/blog/java/virtual-function-in-java/ – Kenneth Aug 01 '18 at 14:14
  • "...otherwise there will be no instantiation possible". Is it required that a `Person` be instantiated, or will only its subclasses be instantiated? – meat Aug 01 '18 at 14:14
  • then why do you need reference variable of parent class `Person p1`?? You can use `Student s1 = new Student();` – Shubhendu Pramanik Aug 01 '18 at 14:16
  • I know that in this specific situation, it's more logical to use Student s1 = new Student() but it was an example (I tried to keep it simple). In my code, I have an ArrayList of Person and I want to know if there is a way to use "person.get(i).printInfos()" directly – Spn Aug 01 '18 at 14:22
  • 2
    I know it's possible in Java, but I see it as a bad design if a class is neither abstract or final. If you do p3 = new Person(), then what type of person is it? I'd rather make a 3rd subclass of Person like Guest and then do p3 = new Guest(). And make Person abstract. – EasterBunnyBugSmasher Aug 01 '18 at 14:24
  • @EasterBunnyBugSmasher yes, that's what I mean, thanks. – Soner from The Ottoman Empire Aug 01 '18 at 14:25

2 Answers2

2

You should exactly declare Person as interface. Logically, Person shouldn't be instantiated. Defining new class and empty-bodied method are superfluous in this case.

If you insist on the gobbledygook approach, there is no sane way to do that other than defining new class.

interface Person {
   public void printInfos();
}

class Student implements Person {
     @Override
     public void printInfos(){
          System.out.println("studentInfos");
     }
}

class Teacher implements Person {
     @Override
     public void printInfos(){
          System.out.println("teacherInfos");
     }
}

main:
Person p1 = new Student();
Person p2 = new Teacher();
user85421
  • 28,957
  • 10
  • 64
  • 87
0

Please tell me more about your needs for this class. Is there any good reason why you would want to create Person instance? If not it is clearly an abstract class for me and I think you should make it abstract.

You will still have option to declare constructor, some method that are "default" for the subclasses (an provide them an implementation) and make printInfos an abstract method.

abstract class Person {
    abstract void printInfos();
}

class Student extends Person {
    public void printInfos(){
        System.out.println("studentInfos");
    }
}

class Teacher extends Person{
public void printInfos(){
        System.out.println("teacherInfos");
        }
        }
MDaniluk
  • 62
  • 2
  • 2
  • 16
  • Sorry for the lack of informations. I had an ArrayList of Person in my code and I wanted to know if there is a way to use "person.get(i).printInfos()" directly. But it seems that it was a bad design (and I agree) and that it would be better to create a third class. – Spn Aug 01 '18 at 14:37
  • @snr I can not agree with link you provide and I think abstract class is much more elegant choice for this situation. 1. Interface and abstract classes is very similiar since java8 (for example interface default methods give you the option to provide an implementation for all subclasses) but in this case abstract class is better choice, because it allow you to declare constructor that all subclasses will inherit. – MDaniluk Aug 01 '18 at 14:48
  • @MDaniluk I would guess that a person mentioned `default` methods. Nonetheless, `default` methods don't serve the purpose. **These are for certainly backwards compatibility**. Thus similarity may be technically, but not sanely. https://stackoverflow.com/questions/19998309/purpose-of-default-or-defender-methods-in-java-8 – Soner from The Ottoman Empire Aug 01 '18 at 14:53
  • @snr It's the first time I hear about interface, I'm doing some researches on it because I feel that it makes my code a lot easier to manipulate. My ArrayList contains instances of "Person" but if I correctly understood, we can't do this if Person is an interface. So maybe I should create a third class, and declare an ArrayList in the interface, and then use it ? – Spn Aug 01 '18 at 14:55
  • 1
    @Spn ArrayList will work as interface. It's just a reference. – Soner from The Ottoman Empire Aug 01 '18 at 14:56