Template method pattern issue - java

if I have an abstract Parent class which has a templateMethod and a concrete Child class :
abstract class Parent
{
final void templateMethod()
{
foo();
}
abstract void foo();
}
class Child extends Parent
{
#Override
void foo()
{
System.out.println("foo");
}
}
what should i do if i only want the user to know that templateMethod and do not want to expose foo method to class Child's user while let the Child class define the implementation of foo method ?
Or, is template method not suitable in this case? Then, is there any other strategies i can use?

As suggested by JB Nizet in the comment, you could do:
abstract class Parent {
final void templateMethod() {
foo();
}
abstract protected void foo();
}
class Child extends Parent {
#Override
protected void foo() {
System.out.println("foo");
}
}
Since Parent.foo() is protected, only subclasses of Parent can call the method.
You might also find this question helpful: What is the difference between public, protected, package-private and private in Java?

Related

Java - calling a method by passing child instance to a function with parameter of parent class type [duplicate]

public class Parent {
....
}
public class Child1 extends Parent {
....
public void foo() {
....
}
}
public class Child2 extends Parent {
....
public void foo() {
....
}
}
Here method foo() only exists in the Child classes and CAN NOT be added to the Parent class (not even abstract method). In this situation when I want to call the foo() method on obj which is Parent class's reference then I need to use intanceof with multiple if..else which I want to avoid.
Parent obj = ...// Object of one of the child classes
obj.foo();
EDIT: I Need to use type of obj as Parent only. Else I will not be able to call methods on obj which exists in Parent class.
My Solution: The approach that I am thinking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
Is there a better approach ? Or any improvement to this one?
You can't do it with parent object reference until an unless method is declared in parent class/interface itself.
You have to downcast it to child class because parent class/interface doesn't have any knowledge about the child class other than the contract defined between them.
Here contract means abstract methods.
you can try in this way where there is no need to put a check it.
FooInterface sc =new Child1();
sc.foo();
...
interface FooInterface{
void foo();
}
public class Parent {
}
public class Child1 extends Parent implements FooInterface{
public void foo() {
}
}
public class Child2 extends Parent implements FooInterface{
public void foo() {
}
}
The approach that I am finally taking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
The polymorphism is applied on object reference, not a type. When you call
FooInterface obj = ...// Object of one of the child classes
obj.foo();
the child class method foo() is called.
If you want to typecast only then there is no need of adding interface. You can typecast it to your desired class and call the method. Example
public class HelloWorld {
public static void main(String args[]) throws FileNotFoundException {
SuperClass sc =new Child1();
if(sc instanceof Child1)//Do same for Child2
((Child1)sc).foo();
}
}
class SuperClass {
}
class Child1 extends SuperClass{
public void foo(){
System.out.println("From child1");
}
}
class Child2 extends SuperClass{
public void foo(){
System.out.println("From child2");
}
}
Output :
From child1
You could implement an AbstractChild inheriting from Parent and then extend this class instead of Parent:
public class Parent {
....
}
public abstract class AbstractChild extends Parent{
public abstract void foo();
}
public class Child1 extends AbstractChild {
....
public void foo() {
....
}
}
public class Child2 extends AbstractChild {
....
public void foo() {
....
}
}
So you need to only check if your instance is instanceof AbstractChild.

Method overriding with different parameters

Lets say I have a parent class:
class Parent{
public void aMethod() {
//Some stuff
}
}
and it's child class:
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
}
Now the child has both methods with different parameters. This does method overloading. But I need method overriding, i.e, If someone tries to call aMethod() with the object of child class then the method of child class should be called or say method of parent class should not be accessible. But I can't change the access modifier of the parent class because the parent class has other children as well and they need the method as is.
So any suggestions?
You can override the Parent's method in the Child class and throw an exception:
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
#Override
public void aMethod() {
throw new UnsupportedOperationException();
}
}
Or, if you want the existing method of the Child class to be executed :
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
#Override
public void aMethod() {
aMethod (someIntValue);
}
}
Either way Parent's implementation of aMethod() will never be executed for instances of class Child.
this
void aMethod() {
and this
void aMethod(int number)
are totally different methods (their signature is different) so there is not way to say that aMethod(int number) is overriding aMethod()
so what you can do?:
override the only method you can and the OVERLOAD it
public class Child extends Parent {
#Override
public void aMethod() {
// TODDY
}
//here overload it
public void aMethod(int number){
// TODDY
}
}
You can implement a version of aMethod in the Child class and it will be called instead of the parent's version when you call that method on any instance of the Child class.
You don't need to change the Parent's signature to override the method because both public and protected methods can be overridden.
class Child extends Parent {
#Override
public void aMethod() {
// TODO
}
public void aMethod(int number){
//Some other stuff
}
}

implement an abstract method in derived class as static

I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().

How to call the abstract method from a class which is not in hierarchy in java

Below is my code. I have the abstract class Myabatract which has the method myMethod and I have a subclass MySubClass in which I have overridden the myMethod. In my client class
I have a method callMethod from which I want to directly call the myMethod of Myabatract class is this possible?
abstract class Myabatract {
public void myMethod() {
System.out.println("This is from Myabatract");
}
}
class MySubClass extends Myabatract {
public void myMethod() {
System.out.println("This is from MySubClass");
super.myMethod();
}
}
class Client{
public void callMethod(){
}
}
You can create an anonymous implementation of the abstract class. This is particularly easy given the fact that it does not use any abstract methods.
class Client {
public void callMethod() {
Myabatract instance = new Myabatract() { /* nothing to implement*/ };
instance.myMethod();
}
}
As a user of the MySubClass type, you have no way to call the Myabatract method because it has been overridden, unless MySubClass were to expose it. Your only recourse would be to create another method that exposed the super method from within MySubClass (or other child implementations).
It's important to note that this will not work:
class Client {
public void callMethod() {
MySubClass instance = new MySubClass() {
#Override
public void myMethod() {
super.myMethod();
}
};
instance.myMethod();
}
}
super is the non-anonymous class, MySubClass, which means nothing is actually changing. Interestingly, this can be worked around in C++ using the scope resolution operator (::).
It's also worth pointing out that you are calling super.myMethod() in your implementation of MySubClass, which does invoke the Myabatract method.

Identifying the child class calling a base class static function

Suppose I have a base class with a function foo
public class Base
{
protected static void foo()
{
// ToDo - what is the name of the child class calling me?
}
}
and at least one child class containing a static initialiser that calls foo
public class Child extends Base
{
static
{
foo();
}
}
Is there a way of foo() knowing which child class has called it? I'm presuming there's a reflection technique I can use.
The simplest way is to pass an argument. For example
public class Base {
protected static void foo(Class<?> type) {
if (type == Child.class) {
}
}
}
public class Child extends Base {
static {
foo(Child.class);
}
}
However, if you need to do something that depends on the child class then I recommend looking for a solution that leverages abstract methods and polymorphism.
public Base {
protected static void foo(Base child) {
child.doFoo();
}
protected abstract void doFoo();
}
public Child extends Base {
static {
foo(new Child());
}
#Override
protected void doFoo() {
//do the child specific thing here
}
}
You can get the class by using the getClass method, like:
o.getClass()
also, if you have a class c and you need to check whether o is an instance of c, you can use instanceof, like this:
o instanceof c
Cheers.

Categories