What is the benefit of base class variable holding derived class object? - oop

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.

Related

Testing class that extends abstract class

I need to write a test for a class that extends an abstract class. Problem starts when I need to test a method that has super reference. So the code looks something like this:
public abstract class AbstractClass{
public String someMethod();
}
public class MyClass extends AbstractClass {
methodToTest(){
//somecode
super.someMethod();
}
}
Any idea how should I get around it?
EDIT:
I'm sorry, I am still new to unit testing and just a moment ago figured out why exactly this is not working as I would like to. MyClass in the example above actually contains a initialization block that sets some fields declared in AbstractClass that are used by someMethod so new AbstractClass.someMethod() didn't give me the same results as super.someMethod. And, as I cannot initialize the AbstractClass it would be impossible to get desired results. I figured that I would need to mock it somehow but as I said I am new to this and have no idea how to do that
public abstract class AbstractClass{
String fieldA;
public String someMethod(){
//does something with fieldA
}
}
public class MyClass extends AbstractClass {
{
setFieldA("something");
}
methodToTest(){
//some code
super.someMethod();
//returns some string based on the fieldA value
}
}
UPDATE Here is updated version of my code. Please help me with writing test for that. I would probably be able to get it from there:
public abstract class AbstractClass{
String fieldA;
public String someMethod(){
fieldA = "String" + fieldA;
}
}
public class MyClass extends AbstractClass {
{
setFieldA("Another String");
}
methodToTest(){
fieldA = fieldA + "Yet Another String";
super.someMethod();
return fieldA;
}
}
Your problem is less about unit testing; but more a general misconception how to work with abstract classes.
First of all: if your abstract class needs a field to do its job, then you better not use a setter for that. Instead:
public abstract class Base {
private final String thatField;
public Base(String incoming) {
thatField = incoming;
}
..
public class Derived extends Base {
public Derived(String incoming) {
super(incoming);
}
In other words: it seems that this field is an important part of your classes. So make that explicit. And by enabling it to be set via constructor, you also ensure that
you control when/how the field gets set
you get help from the compiler - by making the field final, you get errors when you forget initializing
Beyond that: when you start testing some class ... it shouldn't matter if that class just extends Object; or if it extends some other class; even when extending an abstract class.
That is about what can be said here; given the fact that your example doesn't contain any specific details about what your code is "really" doing.

How Dynamic binding works in java

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
}
}

Using Javassist library to detect runtime type of a method caller

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();

Read-only properties inheritance: abstract or set-protected

Let's say that class A is abstract and defines read-only properties that class B, which inherits from it, must provide. Is it better practice to define such properties as abstract or as set-protected:
public abstract class A
{
public abstract int Value { get; }
}
public class B : A
{
public override int Value { get { return 1; } }
}
OR
public abstract class A
{
public int Value { get; protected set; }
}
public class B : A
{
public B()
{
Value = 1;
}
}
I think that the first solution is probably better but i'd like to hear other opinions.
It depends on what you mean by read-only. If you mean read-only for callers, then I would prefer the second solution.
The first solution forces the child class to implement get, which is good. But it prohibits the child from implementing set (even a protected one), which is bad.
With the second solution, the whole Value interface is defined by the base class, which is good, and the child class is still able to set Value when it chooses, which is also good.
If on the other hand by "read-only" you mean truly read-only, in that not even the child class is allowed to set Value, then the first solution is better. You even get the right compile error if you do try to set it.

Base class and derived class

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.