Suppose I have two classes A and B where A is a superclass of B. Now, I write a function (override), say funct() in both the classes. Then, if I want to call the funct() in A from an object of B, is it possible?
class A {
public void f() {...}
}
class B extends A {
#Override public void f() { super.f(); }
}
Is that what you want?
If instead you want to call A#f() directly on an instance of type B, you must provide a placeholder function for that:
class B extends A {
#Override public void f() { ... }
public void superF() { super.f(); }
}
new B().f(); // calls B#f();
new B().superF(); // calls A#f();
I have trick such as this situation to operate it in an illogical manner using Flag argument in funct() method :D, like this:
class A {
public void funct(boolean callSuper) {
// avoid using callSuper arg here
}
}
class B extends A {
#Override
public void funct(boolean callSuper) {
if (callSuper) {
super.funct(callSuper);
return;//if return type is void
} else {
//do here the functionality if the flag is false
}
}
}
or
class A {
public void funct() {
}
}
class B extends A {
private boolean callSuper = false;
#Override
public void funct() {
if (callSuper) {
super.funct(); // call A.funct() functionality
setCallSuper(false);
} else {
//do here the functionality of B.funct() if the flag is false
}
}
public void setCallSuper(boolean callSuper){
this.callSuper = callSuper;
}
}
Given classes like
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {...}
}
You ask
Then, if I want to call the funct() in A from an object of B, is it
possible?
So let's take
B b = new B();
b.funct();
A a = b;
a.funct();
((A)b).funct();
The above all do the same thing because of polymorphism and late-binding.
The only way to call the superclass' implementation is to get a reference to that member through the super keyword.
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {
super.funct();
}
}
Related
I have the following classes.
interface interface1() {
void function1()
}
interface interface2 extends interface1() {
void function2()
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
}
class implementation2 implements interface2 () {
#Override
void function1() {
// Implement
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface instanceOf(interface2)) {
interface.function2();
}
}
}
Could you please tell if there is a way to prevent using instanceOf? I read visitor pattern could be used but I am not getting the exact changes to be done.
Following are the classes after discussing with Alex R below (instanceOf is avoided since it is not recommended, visitor pattern is avoided since it still leads to empty visit functions). Please let me know if this can be done better using other design patterns.
interface interface1() {
void function1();
boolean isFunction2Applicable();
default void function2() {
}
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return false;
}
}
class implementation2 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return true;
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface.isFunction2Applicable()) {
interface.function2();
}
}
}
One way to do so is to define some method in the base interface and override it in the sub-interfaces or implementations. In the following example I'm using a default method but you don't have to do so; the method can be abstract and only be implemented in the implementations:
interface I1 {
void function1();
default void execute() {
function1();
}
}
interface I2 extends I1 {
void function2();
#Override
default void execute() {
function1();
function2();
}
}
public static void main(String[] args) {
List<I1> ifaces = new ArrayList<>();
for (I1 iface : ifaces) {
iface.execute();
}
}
public abstract class CommonClass {
abstract void send(<what should i put here???>) {}
}
public class ClassA extends CommonClass {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass {
void send(List<Post> postList) {
// do stuff
}
}
I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?
You could make it generic on some type T. Like,
public abstract class CommonClass<T> {
abstract void send(List<T> al);
}
And then, to implement it - use the generic. Like,
public class ClassA extends CommonClass<Comments> {
#Override
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,
public abstract class AbstractSender<T> {
abstract void send(List<T> al);
}
and then
public class CommentSender extends AbstractSender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender extends AbstractSender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).
Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);
public interface ISender<T> {
void send(List<T> al);
}
public class CommentSender implements ISender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender implements ISender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html
With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.
public abstract class CommonClass<T> {
abstract void send(List<T>) {}
}
public class ClassA extends CommonClass<Comment> {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
void send(List<Post> postList) {
// do stuff
}
}
You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm
Example
The abstract class
public abstract class CommonClass {
public abstract <T> void send(List<T> data);
}
Its child
public class Child extends CommonClass {
public <T> void send(List<T> data) {
// code here
}
}
Retrieving the list's contents
Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.
for (T t : data) {
// to check if t is a string
if (t instanceof String) {
// code
}
}
You can also use lambdas to retrieve every element in the list.
I'm new in java, I want to call method class from implemented Class with interface without know class name "ClassA", which only know Object c and I have 2 file.
File (1) CobaInterface.java
package cobainterface;
public class CobaInterface {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ClassA{
public Integer getTwo(){
return 2;
}
}
interface MyInterface {
public void myMethod();
//here interface
public void myMethodFromClassA(Object c);
}
File (2) : ImpementedClass.java
package cobainterface;
public class ImplementedClass extends CobaInterface {
public void myMethodFromClassA(Object c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
How about if I want to call method getTwo() from ClassA without know Class Name, which only know Object c from file (2) as describe in code above. Thanks for advance.
You should use generic types so the implementation knows what the object will be,
interface MyInterface<T> {
public void myMethod();
//here interface
public void myMethodFromClassA(T c);
}
The impl becomes,
package cobainterface;
public class ImplementedClass Implements MyInterface<ClassA> {
public void myMethodFromClassA(ClassA c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
All together,
class Scratch {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ImplementedClass implements MyInterface<ClassA> {
#Override
public void myMethod() {
}
#Override
public void myMethodFromClassA(ClassA c) {
System.out.println(c.getTwo());
}
}
class ClassA {
public Integer getTwo() {
return 2;
}
}
interface MyInterface<T> {
void myMethod();
void myMethodFromClassA(T c);
}
You could also do a cast
System.out.println((MyClass)c.getTwo());
but you will lose all benefit of type saftey.
Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}
Consider the following classes
Class A{
public void m1(){
System.out.println("test in A.m1()");
}
public void m2(){
//do something a
}
}
Class B{
public void m1(){
//do something b
}
public void m2(){
//do something b
}
}
Class C{
public void m1(){
//do something c
}
public void m2(){
//do something c
}
}
Class T{
public void m3(Object obj1){
obj1.m1();
}
public void m4(Object obj1){
A a=new A();
m3(a);
}
}
So now my question is, is there any way I can send an open object to a method which will detect what type of object it is and call method of that object class. In this example I am hoping to see the output: "test in A.m1()"
You can use Java's Reflection API to query an arbitrary object to see if it has a method named m1 or m2 and then invoke it. But that is pretty ugly.
Is there anything from stopping you using an interface? Example below (where "..." indicates places where you would put your specific implementation):
interface MyMethods {
public void m1();
public void m2();
}
class A implements MyMethods {
public void m1() { ... }
public void m2() { ... }
}
class B implements MyMethods {
...
}
class C implements MyMethods {
...
}
class T {
public void m3(MyMethods obj1) {
obj1.m1();
}
public void m4(Object obj1) {
// Call m3 three times with different object instance types...
A a = new A();
m3(a);
B b = new B();
m3(b);
C c = new C();
m3(c);
}
}