I am beginner to java and trying to understand Dynamic binding
when i come across this below example,
class Animal{}
class Dog extends Animal{
public static void main(String args[]){
Dog d1=new Dog();
}
}
Here d1 is an instance of Dog class, but it is also an instance of
Animal.
here what i dont understand is,How d1 is also become an instance of Animal class when you do inherit in java.
Can someone explain this concept.
Why they say "d1 is also an instance of Animal", what they really mean is that d1 can be used like an instance of Animal. You can use d1 to do everything an instance of Animal can do, including but not limited to:
Passing d1 to an Animal parameter
public static void method(Animal a) { ... }
...
method(d1); // compiles!
Assigning d1 to a variable of type Animal
Animal myAnimal = d1;
Calling methods that is in the Animal class
d1.move();
The reason why you can do all these is all because of that extends keyword.
Dynamic binding occurs during the run time.It is also known as Late binding as it occurs in the run time.The type of the object cannot be determined during the compile time.The parent class and the child class has the same method but the method is overridden.
Simple example to understand Dynamic binding
class Animal{
void eat(){
System.out.println("Animal is Eating");
}
}
class Dog extends Animal{
void eat(){
System.out.println("Dog is Eating");
}
}
class Test{
public static void main(String [] args){
Animal obj = new Animal();
obj.eat(); // displays Animal is Eating
Animal obj1 = new Dog(); // reference of the parent class
obj1.eat(); // displays Dog is Eating
}
}
Related
I know that javassist.expr.MethodCall.getClassName() returns the compile time type of the method caller because it depends on bytecode analysis. I am wondering if there is an efficient way to get the actual runtime type of the method caller with javassist using some trick or through code inspection.
Here is a simple example to make things clearer.
public interface Animal {
public void eat();
}
public class Dog implements Animal {
#Override
public void eat() {
System.out.println("dog eating");
}
}
public class MainClass {
public static void main(String[] args) {
Animal a = new Dog();
a.eat();
}
}
In this example, I would like to find a way to get a "Dog" object as the method caller for the method "a.eat()"
From the javassist.expr.MethodCall you can easily get the runtime class that has called this method:
CtClass ctc = javassist.expr.MethodCall.getMethod().getDeclaringClass();
Once you have the Javassist representation of the class that called this method that contains everything you need about this class.
PS if you really need a Dog instance you can use reflection taking the name by the CtClass, e.g.:
Class clazz = Class.forName(ctc.getName());
Dog dog = ((Dog)clazz).newInstance();
I know that it is possible to base class variable holding derived class object. Like below....
class Animal
{
public void printName()
{
System.out.println("Print your name");
}
}
public class Tiger extend Animal
{
public void Print()
{
System.out.println("My Name");
}
public void static main(String args[])
{
Animal type1 = new Tiger();
//with this new created type1 varibale. I can only access members of Animal class.
type1.PrintName() // valid
type1.Print() //In-valid
}
}
So what is the usefulness of this? Still I don't see any benefit. Can someone explain me, may be I am missing something. Thanks.
In this case, where the variable is initialized from a child class variable, it isn't terribly useful. The usefulness comes in two cases:
When you have a function parameter with a base class type and you pass in a child class object as the actual argument.
void CareForAnimal(Animal anm) {
anm.Feed();
anm.Sleep();
}
While it's technically possible to allow you to do things with formal parameters you can't do with regular variables, as a language designer it's a lot of complication to make them different for not a lot of benefit.
When you have a base class variable initialized from the result of a method which is itself virtual:
Animal Breed(Animal father, Animal mother) {
Animal child = mother.mater(father);
child.Bathe();
child.Nurse(mother);
return child;
}
Now, you don't know right away which child class child is being initialized with.
i have a question regarding design patterns.
suppose i want to design pig killing factory
so the ways will be
1) catch pig
2)clean pig
3) kill pig
now since these pigs are supplied to me by a truck driver
now if want to design an application how should i proceed
what i have done is
public class killer{
private Pig pig ;
public void catchPig(){ //do something };
public void cleanPig(){ };
public void killPig(){};
}
now iam thing since i know that the steps will be called in catchPig--->cleanPig---->KillPig manner so i should have an abstract class containing these methods and an execute method calling all these 3 methods.
but i can not have instance of abstract class so i am confused how to implement this.
remenber i have to execute this process for all the pigs that comes in truck.
so my question is what design should i select and which design pattern is best to solve such problems .
I would suggest a different approach than what was suggested here before.
I would do something like this:
public abstract class Killer {
protected Pig pig;
protected abstract void catchPig();
protected abstract void cleanPig();
protected abstract void killPig();
public void executeKillPig {
catchPig();
cleanPig();
killPig();
}
}
Each kill will extend Killer class and will have to implement the abstract methods. The executeKillPig() is the same for every sub-class and will always be performed in the order you wanted catch->clean->kill. The abstract methods are protected because they're the inner implementation of the public executeKillPig.
This extends Avi's answer and addresses the comments.
The points of the code:
abstract base class to emphasize IS A relationships
Template pattern to ensure the steps are in the right order
Strategy Pattern - an abstract class is as much a interface (little "i") as much as a Interface (capital "I") is.
Extend the base and not use an interface.
No coupling of concrete classes. Coupling is not an issue of abstract vs interface but rather good design.
public abstract Animal {
public abstract bool Escape(){}
public abstract string SaySomething(){}
}
public Wabbit : Animal {
public override bool Escape() {//wabbit hopping frantically }
public override string SaySomething() { return #"What's Up Doc?"; }
}
public abstract class Killer {
protected Animal food;
protected abstract void Catch(){}
protected abstract void Kill(){}
protected abstract void Clean(){}
protected abstract string Lure(){}
// this method defines the process: the methods and the order of
// those calls. Exactly how to do each individual step is left up to sub classes.
// Even if you define a "PigKiller" interface we need this method
// ** in the base class ** to make sure all Killer's do it right.
// This method is the template (pattern) for subclasses.
protected void FeedTheFamily(Animal somethingTasty) {
food = somethingTasty;
Catch();
Kill();
Clean();
}
}
public class WabbitHunter : Killer {
protected override Catch() { //wabbit catching technique }
protected override Kill() { //wabbit killing technique }
protected override Clean() { //wabbit cleaning technique }
protected override Lure() { return "Come here you wascuhwy wabbit!"; }
}
// client code ********************
public class AHuntingWeWillGo {
Killer hunter;
Animal prey;
public AHuntingWeWillGo (Killer aHunter, Animal aAnimal) {
hunter = aHunter;
prey = aAnimal;
}
public void Hunt() {
if ( !prey.Escape() ) hunter.FeedTheFamily(prey)
}
}
public static void main () {
// look, ma! no coupling. Because we pass in our objects vice
// new them up inside the using classes
Killer ElmerFudd = new WabbitHunter();
Animal BugsBunny = new Wabbit();
AHuntingWeWillGo safari = new AHuntingWeWillGo( ElmerFudd, BugsBunny );
safari.Hunt();
}
The problem you are facing refer to part of OOP called polymorphism
Instead of abstract class i will be using a interface, the difference between interface an abstract class is that interface have only method descriptors, a abstract class can have also method with implementation.
public interface InterfaceOfPigKiller {
void catchPig();
void cleanPig();
void killPig();
}
In the abstract class we implement two of three available methods, because we assume that those operation are common for every future type that will inherit form our class.
public abstract class AbstractPigKiller implements InterfaceOfPigKiller{
private Ping pig;
public void catchPig() {
//the logic of catching pigs.
}
public void cleanPig() {
// the logic of pig cleaning.
}
}
Now we will create two new classes:
AnimalKiller - The person responsible for pig death.
AnimalSaver - The person responsible for pig release.
public class AnimalKiller extends AbstractPigKiller {
public void killPig() {
// The killing operation
}
}
public class AnimalSaver extends AbstractPigKiller {
public void killPing() {
// The operation that will make pig free
}
}
As we have our structure lets see how it will work.
First the method that will execute the sequence:
public void doTheRequiredOperation(InterfaceOfPigKiller killer) {
killer.catchPig();
killer.cleanPig();
killer.killPig();
}
As we see in the parameter we do not use class AnimalKiller or AnimalSever. Instead of that we have the interface. Thank to this operation we can operate on any class that implement used interface.
Example 1:
public void test() {
AnimalKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `AnimalKilleraKiller `
AnimalSaver aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
Example 2:
public void test() {
InterfaceOfPigKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `InterfaceOfPigKiller `
InterfaceOfPigKiller aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
The code example 1 and 2 are equally in scope of method doTheRequiredOperation. The difference is that in we assign once type to type and in the second we assign type to interface.
Conclusion
We can not create new object of abstract class or interface but we can assign object to interface or class type.
suppose we have a class structure where the code is divided in two parts lets us say computer science and business, now this also further divides in terms of country also, say Indian (cs or MBA) and US (cs or MBA).
now let us consider a scenario where i created classes like
1)Education class(parent class)
2) MBA class extends Education class
3) BS (cs) class extends Education class
now in terms of country also i made the classes
4) INDIA_BS class extends BS (cs) class
5)INDIA_MBA class extends MBA class
6) US_BS class extends BS (cs) class
7) US_MBA class extends MBA class
now let us say i write code where the country is set in the classes-method which are lowest in hierarchy (i.e country classes INDIA_BS,INDIA_MBA,US_BS,US_MBA)
but the logic is similar.I pass country name and it is set.
so my questions are
1) is it wise to put the common logic in parent classes(if i do that way) and calling that method from the child class which is lowest in hierarchy).
2) if this is wrong than what are the principles of OOPS that it violate
3) does it violate SOLID principle also if yes then how ?
4) is it decreasing coherence of the child class if i am putting the common code in parent class.
please be elaborate as possible.
thanks
Your class diagram:
i see x violations:
Favor Composition Over Inheritance
Program To An Interface, Not An Implementation
Software Entities Should Be Open For Extension, Yet Closed For Modification
etc
So, i would suggest you use Abstract Factory pattern.
Code:
class Test
{
static void Main(string[] args)
{
IEducationFactory india = new IndianEducation();
IEducationFactory newYork = new USEducation();
IDiplom d1 = india.Create_BSC();
IDiplom d2 = newYork.Create_MBA();
}
}
public interface IDiplom
{
}
public interface IEducationFactory
{
IDiplom Create_MBA();
IDiplom Create_BSC();
}
public class IndianEducation : IEducationFactory
{
public IDiplom Create_MBA()
{
throw new NotImplementedException();
}
public IDiplom Create_BSC()
{
throw new NotImplementedException();
}
}
public class USEducation : IEducationFactory
{
public IDiplom Create_MBA()
{
throw new NotImplementedException();
}
public IDiplom Create_BSC()
{
throw new NotImplementedException();
}
}
And, your class diagram looks like:
I have a question, I have a base class and an another class which derived from the base class. Can we access derived class in the base class.
Thanks in advance
You can access the code in the derived class from the base class code, but only from within an object which is actually a derived class object, and then only if the methods involved are virtual methods.
If you have an object which is itself an instance of the base class, then from within that instance you cannot see derived class code from the base class .
example
public class Baseclass
{
public void Foo()
{
Bar();
}
public virtual void Bar()
{
print("I'm a BaseClass");
}
}
public classs Derived: BaseClass
{
public override void Bar()
{
print("I'm a Derived Class");
}
}
Main()
{
var b = new BaseClass();
x.Foo() // prints "I'm a BaseClass"
// This Foo() calls Bar() in base class
var d = new Derived();
d.Foo() // prints "I'm a Derived Class"
// in above, the code for Foo() (in BaseClass)
// is accessing Bar() in derived class
}
No you can not. If you happen to know the an object declared as the Base class is actually the derived class, you can cast it. But within the base class you can not access the derived class's members.
There are a lot of ways that a base class can access members of a derived class (depending on programming language), but generally it is considered a design smell.
Instead, you usually want the base class to only directly access its own members, and allow derived classes to override methods.