polymorphism in Java

In Java, polymorphism allows multiple types of objects to be passed to a single method or class.
Java object may be accessed using a reference with the same type as the object, a reference that is a superclass of the object, or a reference that defines an interface that the object implements, either directly or through a superclass. Furthermore, a cast is not required if the object is being reassigned to a supertype or interface of the object.
If you use a variable to refer to an object, then only the methods or variables that are part of the variable’s reference type can be called without an explicit cast.
```
interface Act {
  void sound();
}
class Dolphin implements Act {
  public void sound() {
    System.out.println("whistle");
  }
}
class Whale implements Act {
  public void sound() {
    System.out.println("sing");
  }
}
public class Ocean {
  public void check(Act animal) {
    animal.sound();
  }
  public static void main(String[] args) {
    Ocean o = new Ocean();
    o.check(new Dolphin());
    o.check(new Whale());
  }
}
```
Variables in Java do not follow polymorphism, and overriding is only applicable to methods but not to variables. When an instance variable in a child class has the same name as an instance variable in a parent class, then the instance variable is chosen from the reference type.
```
class Super {
    protected String s = "super";
    protected String getVal() {return s;}
}
class Sub extends Super{
    public String s = "sub";
    protected String getVal() {return s;}
}

class Main {
    public static void main(String[] args) {
        Super sub = new Sub();
        System.out.println(sub.s); // super
        System.out.println(sub.getVal()); //sub
    }
}
```