I have this code sample as you can see. But when I try to compile, it gives an error saying in id.input the object reference variable id cannot be found. Can someone please help me?
interface IDisplay{
void print();
void printDetails();
}
interface IInput{
void input();
}
class Book implements IDisplay,IInput{
int bookID;
String title,publisher;
public void print(){
}
public void printDetails(){
}
public void input(){
}
}
class Student implements IDisplay,IInput{
int studentID;
public void print(){
}
public void printDetails(){
}
public void input(){
}
}
class A{
public static void main(String[] args) {
IDisplay id=new Student();
id.print();
id.printDetails();
id.input();
}
}
A Student instance will be able to call all methods of IInput and IDisplay method but, it depends how you manipulate it
Because you stored if in IDisplay, the methods of IInput are not visible
Solution :
Cast in IInput
IDisplay id = new Student();
id.print();
id.printDetails();
((IInput) id).input(); // or ((Student) id).input();
Store in Student type
Student id = new Student();
id.print();
id.printDetails();
id.input();
At compile stage, the compiler only knows that id's reference type is IDisplay, it does not know id's runtime type is Student.
Since IDisplay does not have method input, you got compile error. To make it compile, you can cast it explictly:
((Student)id).input();
Interface IDisplay has only two methods print and printDetails and the method input is in the interface IInput.
In your code, the object id is of type IDisplay (even though it holds a reference to a Student object) and hence you can only call the methods on the interface IDisplay.
You either have to cast the id object to either Student or IInput to call the input method
((Student)id).input();
((IInput)id).input();
Or
have id as type Student.
However, it could be argued that the former violates some OO principles as a IDisplay has to only be an IDisplay and an IInput has to be only an IInput
That is because id is of type IDisplay and not of type Student.
IDisplay does not have method input()
If you want to invoke a method from Student, you can cast it as Student:
((Student)id).input();
or cast as IInput:
((IInput)id).input();
or instantiate as Student:
Student s = new Student();
s.input();
when you instantiate an object (id) type of IDisplay, cause JVM casts it to an object, IDisplay of type.
so it has been instantiated only with implemented methods of interface IDisplay despite you used the constructor of class Student which implements IDisplay and IInput.
if you intend object id to access to implemented methods of the both interfaces IDisplay and IInput, you should modify your code to:
class A{
public static void main(String[] args) {
Student id = new Student();
id.print();
id.printDetails();
id.input();
}
}
Related
May I know how can I use/call the age method? Here is the Student class.
class Student {
public static void address(){
System.out.println("streetB");
}
}
public class School {
public static void main(String[] args) {
Student gg = new Student() {
public void age() {
System.out.println("9");
}
};
//how to call age() method here?
}
}
You are probably looking for something different, as you just created new class here that extends Student class, but it is anonymous so you can just access that new method as it does not belong to Student class.
If you are using java 10 then you can use var
class Student {
public static void address(){
System.out.println("streetB");
}
}
public class School {
public static void main(String[] args) {
var gg = new Student() {
public void age() {
System.out.println("9");
}
};
gg.age();
}
}
But that would be probably pretty bad idea, as there is just no reason to do such weird thing.
(var works here because it can represent that anonymous class at compile time)
You should probably add age field and method to Student class
Since gg is declared as Student and there is no age() method in that class, compiler will not allow you to call gg.age() because it is not guaranteed that every Student instance will be able to support it.
Pre java 10 solutions (if you are using Java 10 or later read this answer)
What you can try is reflection mechanism through which you can
gg.getClass() to get class literal representing actual type of object held by gg variable,
then getDeclaredMethod("age") to get age method declared in that class,
then invoke(gg) to call that method on object held by gg.
In short
gg.getClass().getDeclaredMethod("age").invoke(gg);
Other way would be not assigning created instance of anonymous class to any reference which would limit its possibility and call method directly on created object like
new Student() {
public void age() {
System.out.println("9");
}
}.age();
but this way we can't reuse that object anywhere later (because we don't have reference to it).
I do have class Person, class Student and Student extends Person. As far as I understood, it goes the following with static binding:
class Person {
talk(Person p) {
print("Hi by person.");
}
}
class Student extends Person {
talk(Student s) {
print("Hi by stud.");
}
}
Now if I instantiate and call method:
Person x = new Student();
talk(x);
// output: "Hi by person." because of static binding, am I right?
My Question:
What if only class Student has a method talk(Student s). Now I call talk(x). Since I usually should get talk() method from class Person, what happens when there is no such method?
EDIT: I tried to run it and it gives me an Compile Error. Ok, but why does this happen? I learned that the compiler will first go to the subclass and search for the method and if it's there, then it gets executed?
Don't exist dynamic binding for overloaded methods ...
and Student is a Person so method talk from Person invoked
class Test{
public Test(){
System.out.println("I am here");
return;// not getting error
}
public static void main(String[] args){
Test test = new Test();
}
}
I am java beginner. My tutor told me that constructor returns an object and showed me the above example. is it really happening because method is not returning any value but the return;is not getting an error.
No, a constructor initialises an object that's already been created. It doesn't return an object. Your tutor is wrong.
You don't need to write return; inside a constructor, unless you're returning before the end of the code.
this line of code
return;
dose not mean return value but it just end the execution of contractor and since it's in the last line so it's not necessarily
situation where you use return in constructor
class Test
{
private int a;
public Test(int a)
{
System.out.println("I am here");
if(a>10)
{
System.out.println("I'm Executed but not the rest of code");
return;
}
System.out.println("I'm the last line of constructor");
}
...
}
return in constructor its just like return in void method
No. The role of constructor is to initialize the state of the object.
new keyword is responsible to create an object in the heap. In below example, using new keyword you are creating an object and then you are pointing that object with type Test variable name test.
Test test = new Test();
No, that is not true at all
A constructor in Java is a block of code similar to a method that’s called when an instance of an object is created. Here are the key differences between a constructor and a method:
A constructor doesn’t have a return type.
The name of the constructor must be the same as the name of the class.
Unlike methods, constructors are not considered members of a class.
A constructor is called automatically when a new instance of an
object is created.
Example:
class Bike1{
Bike1(){
System.out.println("Bike is created");
}
public static void main(String args[]){
Bike1 b=new Bike1();
}
}
Constructor in java is a special type of method that is used to initialize the object.
Java constructor is invoked at the time of object creation. It constructs the values i.e. provides data for the object that is why it is known as the constructor.
But it doesn't have a return type, I'm afraid your tutor is wrong about this, please rediscuss it with him.
class Car{
Car()
{
System.out.println("Car is created");
}
public static void main(String args[])
{
Car c=new Car();
}
}
I am new to java and I remember in c++ we did something like CLASSNAME::Fn() to avoid ambiguity in inheritance.
Here's my code and I want to have same display methods in both classes and access them explicitly.
public class Main {
public static void main(String args[]){
Emplo e = new Emplo("samuel",19,"designer",465);
e.display(); // here i want to call both display()
}
}
public class Person {
String name;
int age;
Person(String s, int a){
name = s;
age = a;
}
public void dispaly(){
System.out.println("name: "+name+"\nage: "+age);
}
}
public class Emplo extends Person {
String desg;
double sal;
Emplo(String s,int a,String d, double sa){
super(s,a);
desg=d;
sal=sa;
}
void display(){
System.out.println("desg: "+desg+"\nsal: "+sal);
}
}
In java, you can't not call the specific method implementation of the class of the instance.
That is, you can't "bypass" a sub-class method and call a super-class version of the method; calling the super-class method can only be done from within the subclass using super.someMethod().
You can't even invoke a super-super class's version, ie you can't do something like super.super.someMethod()
First of in here you are use two different method. display() in Emplo and dispaly() in Person. SO there is no point of talking ambiguity or overriding make that correct.
Suppose you are corrected that. Then you can't code keep this way
public void display(){ // method in Person
System.out.println("name: "+name+"\nage: "+age);
}
Then
void display(){ // method in Emplo
System.out.println("desg: "+desg+"\nsal: "+sal);
}
You are using weaker modifier to override, So you can't compile this code. You can make public the method in Emplo.
And answer for your last question. you can't do it. can't call both method.
In the second display method call the super class display method by using super keywod as :
super.display(); (should be the first statement of the method)
and there will be no ambiguity because that display method will be called whose object is being created that means that the display() method of Employee will be called in this case
so if you want to call the display method of Person class then you should create the object of that class and reference by That class type like :
Person p = new Person(your data);
p.display() // here display method of person will be called
and No you cannot call both methods from the same reference
In your Emplo class display() method super.dispaly() indicates display() method of immediate super class i.e Person class.
void display(){ // here in Emplo class you can't give more restrictive modifier(i.e `public` to `default`. since in `Person` class it is `public` so it must be `public`.(overriding rule)
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
so put public modifier here:
public void display(){
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
`
Perhaps this answers your question:
public void myMethod()
{ //inherited method
super.myMethod(); //calls base class method
//... add more code to inherited method
}
for details see original source:
In Java, how do I call a base class's method from the overriding method in a derived class?
Please explain the concept of static and dynamic binding in Java.
What I have grasped is that Static binding in Java occurs during compile time while dynamic binding occurs during Runtime, static binding uses Type (Class in Java) information for binding while dynamic binding uses Object to resolve binding.
This is the code for my understanding.
public class StaticBindingTest {
public static void main (String args[]) {
Collection c = new HashSet ();
StaticBindingTest et = new StaticBindingTest();
et.sort (c);
}
//overloaded method takes Collection argument
public Collection sort(Collection c) {
System.out.println ("Inside Collection sort method");
return c;
}
//another overloaded method which takes HashSet argument which is sub class
public Collection sort (HashSet hs){
System.out.println ("Inside HashSet sort method");
return hs;
}
}
and the output of the above program was inside the collection sort method
for dynamic binding...
public class DynamicBindingTest {
public static void main(String args[]) {
Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
vehicle.start(); //Car's start called because start() is overridden method
}
}
class Vehicle {
public void start() {
System.out.println("Inside start method of Vehicle");
}
}
class Car extends Vehicle {
#Override
public void start() {
System.out.println ("Inside start method of Car");
}
}
the output was inside the start method of Car. Please advise: Is this understanding correct and please advise some more examples. Thanks.
Static binding is used at compile time and is usually common with overloaded methods - the sort() methods in your example where the type of the argument(s) is used at compile time to resolve the method.
Dynamic binding (dynamic dispatch) is usually associated with polymorphism and overriding methods - the start() method in your example where the type of the receiver (vehicle) is used at runtime to resolve the method.
I think you have summarized it correctly and shams also correctly added more information for you. Just to add little more information for you first let me step back by stating that the association of method definition to the method call is known as binding. So, static binding as you pointed out correctly, is the binding that can be resolved at compile time by compiler (also known as early binding or static binding). On the other hand, dynamic bidding or late binding it means compiler is not able to resolve the call/binding at compile time (it happens at the run time). See below for some examples:
//static binding example
class Human{
....
}
class Boy extends Human{
public void walk(){
System.out.println("Boy walks");
}
public static void main( String args[]) {
Boy obj1 = new Boy();
obj1.walk();
}
}
//Overriding is a perfect example of Dynamic binding
package beginnersbook.com;
class Human{
public void walk()
{
System.out.println("Human walks");
}
}
class Boy extends Human{
public void walk(){
System.out.println("Boy walks");
}
public static void main( String args[]) {
//Reference is of parent class
Human myobj = new Boy();
myobj.walk();
}
}
source