This question already has answers here:
Multiple inheritance on Java interfaces
(5 answers)
Closed 7 years ago.
public class Test implements X, Y { //X.Y interface are shown below
public void myMethod() {
System.out.println(" Multiple inheritance example using interfaces");
}
public static void main(String[]args) {
Test t=new Test();
t.myMethod();
System.out.println(t.a); //compile time error ambigious field
}
}
Please help me to solve this issue
interface X {
public void myMethod();
int a = 0;
}
interface Y {
int a = 9;
public void myMethod();
}
Any variable defined in an interface is, by definition, public static final, in other words it's just a constant, it's not really a field (since there are no fields in interfaces).
So the compilation error you get points out that the compiler doesn't know witch constant you refer to.
You have 2 options here:
change the name of the constant in one of the interfaces, for example in interface Y declare int b = 9;
inside the main method point to a concrete constant: System.out.println(X.a);
Adding to one of the answer already provided.
If a class implements two interfaces and each interface have method with same signature and same name, then you are effectively defining only one method and they are same. If you have two methods of same name but different return types then there will be a compilation error.
Example ->
public interface A {
int a = 0;
void myMethod();
}
public interface B {
int a = 0;
void myMethod();
}
public class Test implements A, B {
#Override
public void myMethod() {
// My method is defined for both A and B
System.out.println(" Multiple inheritance example using interfaces");
}
public static void main(String[] args) {
Test object = new Test();
((A)(object)).myMethod();
((B)(object)).myMethod();
System.out.println(((A)object).a); //To print constant of A
System.out.println(((B)object).a); //To print constant of B
}
}
//Let's see other example
public interface A {
void myMethod();
}
public interface B {
boolean myMethod(); //changed void to boolean
}
public class Test implements A, B {
#Override
public void myMethod() { //Compilation error here, return type is incompatible
}
}
myMethod implements both myMethod declarations. I believe your problem is that in the two separate interfaces a has different values and is before and after the declaration of myMethod. The order is not important, since myMethod will surely be called after the declaration of a, but the difference of a values might cause some logical discrepancies. Maybe you could implement a getter for it as well, to handle the situation.
Related
Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?
Ex:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
#Override
public int f() { // from which interface A or B
return 0;
}
}
If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.
Compatibility example
Here's an example where you have an interface Gift, which has a present() method (as in, presenting gifts), and also an interface Guest, which also has a present() method (as in, the guest is present and not absent).
Presentable johnny is both a Gift and a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
#Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
The above snippet compiles and runs.
Note that there is only one #Override necessary!!!. This is because Gift.present() and Guest.present() are "#Override-equivalent" (JLS 8.4.2).
Thus, johnny only has one implementation of present(), and it doesn't matter how you treat johnny, whether as a Gift or as a Guest, there is only one method to invoke.
Incompatibility example
Here's an example where the two inherited methods are NOT #Override-equivalent:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
This further reiterates that inheriting members from an interface must obey the general rule of member declarations. Here we have Gift and Guest define present() with incompatible return types: one void the other boolean. For the same reason that you can't an void present() and a boolean present() in one type, this example results in a compilation error.
Summary
You can inherit methods that are #Override-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE #Override-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.
The compiler does not have to identify which method is for which interface, because once they are determined to be #Override-equivalent, they're the same method.
Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
References
JLS 8.4.2 Method Signature
JLS 8.4.8 Inheritance, Overriding, and Hiding
JLS 8.4.8.3 Requirements in Overriding and Hiding
JLS 8.4.8.4 Inheriting Methods with Override-Equivalent Signatures
"It is possible for a class to inherit multiple methods with override-equivalent signatures."
This was marked as a duplicate to this question https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
You need Java 8 to get a multiple inheritance problem, but it is still not a diamon problem as such.
interface A {
default void hi() { System.out.println("A"); }
}
interface B {
default void hi() { System.out.println("B"); }
}
class AB implements A, B { // won't compile
}
new AB().hi(); // won't compile.
As JB Nizet comments you can fix this my overriding.
class AB implements A, B {
public void hi() { A.super.hi(); }
}
However, you don't have a problem with
interface D extends A { }
interface E extends A { }
interface F extends A {
default void hi() { System.out.println("F"); }
}
class DE implement D, E { }
new DE().hi(); // prints A
class DEF implement D, E, F { }
new DEF().hi(); // prints F as it is closer in the heirarchy than A.
As far as the compiler is concerned, those two methods are identical. There will be one implementation of both.
This isn't a problem if the two methods are effectively identical, in that they should have the same implementation. If they are contractually different (as per the documentation for each interface), you'll be in trouble.
There is nothing to identify. Interfaces only proscribe a method name and signature. If both interfaces have a method of exactly the same name and signature, the implementing class can implement both interface methods with a single concrete method.
However, if the semantic contracts of the two interface method are contradicting, you've pretty much lost; you cannot implement both interfaces in a single class then.
Well if they are both the same it doesn't matter. It implements both of them with a single concrete method per interface method.
As in interface,we are just declaring methods,concrete class which implements these both interfaces understands is that there is only one method(as you described both have same name in return type). so there should not be an issue with it.You will be able to define that method in concrete class.
But when two interface have a method with the same name but different return type and you implement two methods in concrete class:
Please look at below code:
public interface InterfaceA {
public void print();
}
public interface InterfaceB {
public int print();
}
public class ClassAB implements InterfaceA, InterfaceB {
public void print()
{
System.out.println("Inside InterfaceA");
}
public int print()
{
System.out.println("Inside InterfaceB");
return 5;
}
}
when compiler gets method "public void print()" it first looks in InterfaceA and it gets it.But still it gives compile time error that return type is not compatible with method of InterfaceB.
So it goes haywire for compiler.
In this way, you will not be able to implement two interface having a method of same name but different return type.
Try implementing the interface as anonymous.
public class MyClass extends MySuperClass implements MyInterface{
MyInterface myInterface = new MyInterface(){
/* Overrided method from interface */
#override
public void method1(){
}
};
/* Overrided method from superclass*/
#override
public void method1(){
}
}
The following two approaches can also be taken to implement both the duplicate methods and avoid ambiguity -
APPROACH 1:
App.java -
public class App {
public static void main(String[] args) {
TestInterface1 testInterface1 = new TestInterface1();
TestInterface2 testInterface2 = new TestInterface2();
testInterface1.draw();
testInterface2.draw();
}
}
TestInterface1.java -
public class TestInterface1 implements Circle {
}
TestInterface2.java -
public class TestInterface2 implements Rectangle {
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle
APPROACH 2:
App.java -
public class App {
public static void main(String[] args) {
Circle circle = new Circle() {
};
Rectangle rectangle = new Rectangle() {
};
circle.draw();
rectangle.draw();
}
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle
This question already has answers here:
What is the difference between dynamic and static polymorphism in Java?
(14 answers)
Closed 3 years ago.
Why method overloading called as static or compile-time polymorphism
sample in Java.
class StaticPolymorphismSample {
void polymorphicMethod(int a) {
}
void polymorphicMethod(int a, int b) {
}
void polymorphicMethod(String a) {
}
void nonPolymorphicMethod(int a) {
}
void nonPolymorphicMethod1(int a) {
}
}
so my question is.
Why we say that method overloading ( in this case polymorphicMethod methods ) are static polymorphism , but another methods( nonPolymorphicMethod(int a) nonPolymorphicMethod1(int a) ) are not polymorphism.
technically I cannot see different between method with same name and different parameters and method with different,
all answers in here and topics in google is not applicable for my question.
For nonPolymorphicMethod1(int a) the reason this wouldn't be considered polymorphic is because it has a different name from the other nonPolymorphicMethods.
For nonPolymorphicMethod( int a, int b ) and nonPolymorphicMethod( int a ) these aren't considered polymorphic as they don't take the same parameters. Edit This is Wrong See Next Line
The other methods you've shown are polymorphic due to their sharing of a name, but differing parameter types or number of parameters.
A better example of polymorphism in methods would be :
public abstract class ClassA
{
public Object getObject()
{
return new Object();
}
}
public class ClassB extends ClassA
{
#Override
public ClassB getObject()
{
return new ClassB();
}
}
public class ClassC extends ClassA
{
#Override
public ClassC getObject()
{
ClassC example = new ClassC();
example.doStuff();
return example;
}
private void doStuff()
{
// Do Something To Change The Object
}
}
I have one class and one interface:
public interface A {
public void getNum();
}
public class B {
public void getNum() {
System.out.println("4");
}
}
public class C extends B implements A {
protected void getNum() {
System.out.println("3");
}
}
Now my question is, why this code is giving compilation error and how can we avoid it. Is there any way in which we can override this method in class C?
From Java Language Specification:
jls-8.4.8.3
The access modifier (ยง6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows:
If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
...
Notice that you are trying to override public method getNum() inherited from class B (and also from interface A) with new one that has protected access modifier. It means that you are trying to reduce visibility of this method which according to specification is incorrect.
To be able to override this method you need to use public access modifier with your new version of that method.
Why you cant reduce visibility? Take a look at below code which uses your classes but is placed inside some other package and ask yourself "how should this code behave?".
package my.pckage;
import your.pckage.A;
import your.pckage.C;
public class Test{
public static void main (String[] args){
C C = new C();
c.getNum();// ERROR: Test class doesn't have access to `c`s protected method.
// Why should it have, Test doesn't extend C.
A a = (A)c;// Lets try using other reference
a.getNum();// Should `a` have access to method that is protected in `C`?
// If yes, then what is the point of declaring this method
// protected if all I would have to do to get access to it is
// casting instance of C to A interface?
}
}
Fix the typos and try again ;)
public interface A {
public void getNum();
}
public class B {
protected void getNum() {
System.out.println("4");
}
}
public class C extends B implements A {
public void getNum() {
System.out.println("3");
}
}
First of all scope should be from lower to higher while you are overriding method in Java. scope of subclass method should be high then super class for e.g
Valid Overriding
class B {
protected void getNum() {
System.out.println("4");
}
class C extends B {
public void getNum() {
System.out.println("3");
}
InValid Overriding
class B {
public void getNum() {
System.out.println("4");
}
class C extends B {
protected void getNum() {
System.out.println("3");
}
Your second problem is you have created two public class which is not valid you can create only one public class in your java file.
When you implement an interface you need to compulsorily override it to provide concrete implementation of function(unless the class implementing the interface is abstract). In your case you are implementing an interface which make you implement getNum() function and due to overriding class you have another function with same signature which is not allowed. So you get compilation error.
Possible solution : You can make B as an interface.
The explanation by Pshemo is perfectly right that you can not reduce visibility of overridden or the interface functions.
Lets take an exapmle
class B
{
protected void getProtected1()
{
System.out.println("4");
}
protected void getProtected2()
{
System.out.println("4");
}
public void getPublic1()
{
System.out.println("4");
}
public void getPublic2()
{
System.out.println("4");
}
}
class C extends B
{
#Override
private void getPublic1() //COMPILATION ERROR : Cannot reduce the visibility of the inherited method from myzeromqApp.B
{
System.out.println("3");
}
#Override
protected void getPublic2() //COMPILATION ERROR :Cannot reduce the visibility of the inherited method from myzeromqApp.B
{
System.out.println("3");
}
#Override
private void getProtected1() //COMPILATION ERROR : Cannot reduce the visibility of the inherited method from myzeromqApp.B
{
System.out.println("3");
}
#Override
public void getProtected2() // NO ERROR IT MEANS YOU ARE ALLOWED TO INCREASE THE VISIBILITY
{
System.out.println("3");
}
}
From the above example it is clear that you are not allowed to decrease the visibility of function in any case.
In your question you are trying to implement the interface function and we know interface in Java has rules that,
Method: only public & abstract are permitted
Field: (Variables) only public, static & final are permitted
As thumb of rule, you can never decrease the visibility, of overridden or implemented methods or variables and for interface it is always public (if visibility is concerned) so those should always be public in implemented classes.
As stated, only one public class can be used per file. So, to have them all public, one must create three separate .java files. I will write the code up below, as well as detailing how to override the method to use the correct version of it in each case.
One may always have methods with the same name, but for overriding, they must have different argument lists. This is one of the compiler errors, you have three methods with the same argument lists, namely none. You may create and call the method with the correct argument list to achieve the desired result.
A.java:
package stackOverflow.tests; // Sample package for visibility
public Interface A {
public void getNum(int a); // Method takes a single integer argument
}
B.java:
package stackOverflow.tests;
public class B {
protected void getNum(int a, int b) { // Method takes two integer arguments, differing in the argument list but equal in name
System.out.println("4");
}
}
C.java:
package stackOverflow.tests;
import stackOverflow.tests.A; // Importing both classes to use their methods
import stackOverflow.tests.B;
public class C extends B implements A {
public void getNum(int a, String x) { // Takes an integer and a string argument
System.out.println("3");
}
public void getNum(int a) {
//Do nothing, as in A.java, this code is necessary to be able to override the method.
}
public static void main(String[] arguments) { // Sample main method for implementation
C c = new C(); // Instantiating class C
int test = 0; // Initializing two integer variables and one String variable
int test2 = 0;
String test3 = "";
c.getNum(test); // takes one integer, using getNum() from A.java
c.getNum(test, test2); // takes two integers, using getNum() from B.java
c.getNum(test, test3); // takes an integer and a String, using getNum() from C.java
}
}
Output:
4
3
As seen in the code above, the argument lists define which version of the method is used. As a side tip, the definition getNum(int a) is no different from getNum(int b), so this would result in it not compiling.
In order to get this working you can do something like this since there can be only one public class per file and the file name should be the same name as that of the class
public class HelloWorld{
public static void main(String []args){
C obj=new C();
obj.getNum();
}
}
//interface
interface A {
public void getNum();
}
class B {
protected void getNum() {
System.out.println("4");
}
}
class C extends B implements A {
public void getNum() {
System.out.println("3");
}
}
output:
3
A java class file can have only one public class or interface.
Change the visibility of the interface and the defined class to default level or declare it in separate files.
Only public and abstract modifiers can be applied to interface methods. The class implementing the interface cannot change the visibility of the method (we cannot change it from public to protected).
public interface A {
class Aclass {
int constants = 100;
public void display()
{
System.out.println("Inside A");
}
}
public void display();
}
public interface B {
class Bclass {
int constants = 130;
public void display() {
System.out.println("Inside B");
}
}
public void display();
}
public class MultipleInheritance implements A, B {
#Override
public void display() {
A.Aclass a = new A.Aclass();
System.out.println(a.constants);
B.Bclass b = new B.Bclass();
System.out.println(b.constants);
}
public static void main(String args[]) {
new MultipleInheritance().display();
}
}
though it's through interface and not through a concrete class in context to which you are not inheriting anything but still is it not a code reuse even though maintaining a inner classes will be difficult but still it acts as a multiple-inheritance please clearify with memory representation if possible.
Let's review what you actually have in your code. Here you declare interface A and a nested class AClass:
public interface A {
class Aclass {
int constants = 100;
public void display()
{
System.out.println("Inside A");
}
}
public void display();
}
Here you declare interface B and a nested class Bclass:
public interface B {
class Bclass {
int constants = 130;
public void display() {
System.out.println("Inside B");
}
}
public void display();
}
Here you instantiate Aclass:
A.Aclass a = new A.Aclass();
And here you instantiate Bclass:
B.Bclass b = new B.Bclass();
Now note that Aclass and Bclass are two completely unrelated classes. The only common supertype these two share is Object.
Clearly, there can be no talk of multiple inheritance in a case where you don't even attempt to inherit from two types.
Here you do at least attempt to involve two supertypes:
public class MultipleInheritance implements A, B { ... }
but you never involve this type in your code, it's just a container of the main method. This type, while implementing two interfaces, does not multiply inherit anything from them: it inherits two distinct types (Aclass, Bclass). Note also that, even if they had the same name, there would still be no multiple inheritance. Only a naming clash would occur.
Multiple inheritance is strictly about the inheritance of method implementations and clearly you cannot achieve that in Java.
java doesn't support multiple inheritance for classes. But you can implements several interfaces and that is not consider as multiple inheritance.
Follow this link too. Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?
This is not multiple inheritance, but this is the simulation of the same.
The reason behind not allowing Multiple Inheritance in java was the Diamond problem, which does not occur in case of Interfaces see
this for more info
This is not Multiple inheritance as you are not calling an instance of the subclass through the super class as shown below:
A a = new MultipleInheritance();
a.display();
Even if you do that, there is no confusion as the compiler looks for the type of the variable, which is A and not MulipleInheritance to see the validity of the call.
The reason the compiler is not complaining for having two display() methods is because it knows it doesn't matter which one it uses(the one from A or B) as they are both empty. This avoids the confusion that might result had both A and B bean classes as in C++.
I'm confused with polymorphism and I'm wondering if this is consider polymorphism?
I feel it looks kind of weird but it still compiles correctly.
public class Family {
void FamilyInfo() {
System.out.println("This is a family super class");
}
}
public class Grandparents extends Family {
void FamilyInfo() {
System.out.println("Graparents are the elders in the family and they are the sub class of family");
}
}
public class Parents extends Grandparents {
void FamilyInfo() {
System.out.println("The parents are the children of the grandparents and they are the sub sub class for family");
}
}
public class FamilyDemo {
public static void main(String ary[]) {
Grandparents Gp = new Grandparents();
Parents P1 = new Parents();
Gp.FamilyInfo();
P1.FamilyInfo();
}
}
Your method FamilyInfo is being overridden in all three classes in the hierarchy. This is one example of polymorphism.
When you call Gp.FamilyInfo();: It will call the method implemented in Grandparents class and print Graparents are the elders in the family and they are the sub class of family while P1.FamilyInfo(); will call the method in Parents class and print The parents are the children of the grandparents and they are the sub sub class for family.
Thus you can see that same method FamilyInfo() has two different behaviors, which is polymorphic behavior.
Your example is very similar to one mentioned in the tutorial here: Java Tutorial : Polymorphism. So don't get confused.
The example does not demonstrate polymorphism,rather i can just see simple object oriented inheritance.In order that the concept of polymorphism be used the code should be the following.
public class FamilyDemo
{
public static void main(String ary[])
{
Family Gp = new Grandparents();
Family P1 = new Parents();
Gp.FamilyInfo();
P1.FamilyInfo();
}
}
Even though Gp is of type Family, it behaves like type Grandparents because it is initialized with an object of that type.
Then,the following may be expected:
Graparents are the elders in the family and they are the sub class of family.
The parents are the children of the grandparents and they are the sub sub class for family.
Our trainer said that using extends is more of an example of inheritance. But if we use implements(interface), we can say that it is polymorphic because we can implement many interfaces.
e.g.
interface Horse {
void run();
}
interface Eagle {
void fly();
}
public class Pegasus implements Horse, Eagle {
// Implement methods
public void run() {
// do run
}
public void fly() {
// do fly
}
}
The dictionary definition of polymorphism refers to a principle in
biology in which an organism or species can have many different forms
or stages
The basic concept is for a given object to act like another. This is achieved through the use of interfaces and inheritance in Java.
A better example of this would be (with you code as a base)
public class FamilyDemo {
public static void main(String ary[]) {
Family gp = new Grandparents();
Family p1 = new Parents();
dump(gp);
dump(p1);
}
public static void dump(Family family) {
family.FamilyInfo();
}
}
This basically allows Gradparents and Parents to "act" as they are Family
1.What is polymorphism?
In object-oriented programming, polymorphism (from the Greek meaning "having multiple forms") is the characteristic of being able to assign a different meaning or usage to something in different contexts - specifically, to allow an entity such as a variable, a function, or an object to have more than one form.
2. Two Types of polymorphism
a) Static or Compile time Polymorphism
Which method is to be called is decided at compile-time only. Method overloading is an example of this.for example
public class calculation
{
public int add(int x, int y)
{
return x + y;
}
public int add(int x, int y, int z)
{
return x + y + z;
}
}
here you can see there are two functions with the same name but different signatures
b)Dynamic or Runtime Polymorphism.
Run time polymorphism is also known as method overriding. In this mechanism by which a call to an overridden function is resolved at a Run-Time (not at Compile-time) if a base Class contains a method that is overridden.
Class BaseClass
{
Public void show ()
{
Console.WriteLine("From base class show method");
}
}
Public Class DynamicDemo : BaseClass
{
Public void show()
{
Console.WriteLine("From Derived Class show method");
}
Public static void main(String args[])
{
DynamicDemo dpd=new DynamicDemo ();
Dpd.show();
}
}
Technically speaking, this is polymorphism. However, you have chosen a poor example and it seems like you are not quite understanding the idea behind polymorphism. A better example would be something like this.
public abstract class Shape {
public abstract void drawShape();
}
public class Rectangle extends Shape {
public void drawShape() {
// code for drawing rectangle
}
}
public class Circle extends Shape {
public void drawShape() {
// code for drawing circle
}
}
public class FilledRectangle extends Rectangle {
public void drawShape() {
super.drawShape();
// code for filling rectangle
}
}
Then a class that is responsible for the drawing doesn't need to know how to draw each individual shape. Instead, it can do this
public void drawAllShapes(Shape[] myShapes) {
for (int i = 0; i < myShapes.length; ++i) {
myShapes[i].drawShape();
}
}
The goal is to abstract away the concrete implementation and all the details that go with and instead only present a common interface. This makes it a lot easier to work with different classes, as you can see in the last method above.
A good example for polymorphism would be:
public static void print(Family[] family){
for(int i=0; i< family.length; i++){
family[i].FamilyInfo();
}
}
public static void main(String args[])
{
Family[] family = new Family[2];
Grandparents Gp = new Grandparents();
Parents P1 = new Parents();
family[0] = Gp;
family[1] = P1;
//and then send the array to another method which
//doesn't "know" which entry in the array is a parent and which is grandparent
//and there you can loop the array calling family[i].FamilyInfo();
//THIS is the whole idea of polymorphism in a nutshell
print(family);
}
Yes, in your example program you are using inherit and polimorphism, infact both are closed related.
You are using inherit because you extend once Family from Grandparents class, and once Parents class extending Grandparents and you are also using polimorphism because you are writing in your subclasses a method void FamilyInfo which is written in the super class.
You should use #Override in this way:
public class Parents extends Grandparents {
#Override
void FamilyInfo() {
System.out.println("The parents are the children of the grandparents and they are the sub sub class for family");
}
}