Suppose we have the following code:
class Test {
private Test() {
System.out.println("test");
}
}
public class One extends Test {
One() {
System.out.println("One");
}
public static void main(String args[]) {
new One();
}
}
When we create an object One, that was originally called the parent class constructor Test(). but as Test() was private - we get an error.
How much is a good example and a way out of this situation?
There is no way out. You have to create an available (protected, public or default) super constructor to be able to extend test.
This kind of notation is usually used in utility classes or singletons, where you don't want the user to create himself an instance of your class, either by extending it and instanciating the subclass, or by simply calling a constructor of your class.
When you have a class with only private constructors, you can also change the class to final because it can't be extended at all.
Another solution would be having a method in test which create instances of test and delegate every method call from One to a test instance. This way you don't have to extend test.
class Test {
private Test() {
System.out.println("test");
}
public static Test getInstance(){
return new Test();
}
public void methodA(){
//Some kind of implementation
}
}
public class One {
private final Test test;
One() {
System.out.println("One");
test = Test.getInstance();
}
public void methodA(){
test.methodA();
}
public static void main(String args[]) {
new One();
}
}
Make the constructor of test non-private or move One into test.
BTW, your sample code contains a few issues:
classes should be named title case (Test instead of test)
I'd suggest to make the One's constructor private unless it is called from a different class in the same package
Actually, I found there is a way out. Like this:
class Base {
private Base() {
}
public void fn() {
System.out.println("Base");
}
public static class Child extends Base {
public void fn() {
System.out.println("Child");
}
}
public static Base getChild() {
return new Child();
}
}
Now, you can use getChild() to get instance of the extended class.
Related
Let's say I have three Classes A,B,C.
All three do the same thing, but in a different way, they differ in efficiency.
All the method names, variable names inside the three classes are same.
class A{
public static int method(){
......
return result;
}
}
class B{
public static method(){
......
return result;
}
}
class C{
public static method(){
......
return result;
}
}
I have test class, which has a method to test the code in the above three classes. Since this testMethod() is common to all the three classes, is there a way to call this method with objects of classes A,B,C ?
class Test{
public static int testMethod(Object ABC)
{
return ABC.method();
}
public static void main(String[] args){
A a = new A();
SOP(testMethod(a));
B b = new B();
SOP(testMethod(b));
C c = new C();
SOP(testMethod(c));
}
}
The only approach I can think of is creating three different methods for each of the classes, like this.
class Test{
public static int testMethodA(A a)
{
return a.method();
}
public static int testMethodB(B b)
{
return b.method();
}
public static int testMethodC(C c)
{
return c.method();
}
public main()
{
//call to each of the three methods
............
}
What is the best approach to this scenario? Basically I want to have only one method that can test all three classes.
Create an interface with the common method for all classes. Then, make each class implement this interface. In your test code, use the interface as parameter type and pass an instance of each class to the method. Note that when you do this, the method to test should not be static.
In code:
public interface MyInterface {
//automatically public
int method();
}
public class A implements MyInterface {
#Override //important
//not static
public int method() {
/* your implementation goes here*/
return ...;
}
}
public class B implements MyInterface {
#Override //important to check method override at compile time
public int method() {
/* your implementation goes here*/
return ...;
}
}
//define any other class...
Then the test:
public class Test {
//using plain naive console app
public static void main(String[] args) {
MyInterface myInterfaceA = new A();
testMethod(myInterfaceA);
MyInterface myInterfaceB = new B();
testMethod(myInterfaceB);
//and more...
}
public static void testMethod(MyInterface myInterface) {
myInterface.method();
}
}
Or if you prefer to use JUnit:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class MyInterfaceTest {
MyInterface myInterface;
#Test
public void methodUsingAImplementation() {
myInterface = new A();
//code more human-readable and easier to check where the code fails
assertThat(myInterface.method(), equalTo(<expectedValue>));
}
//similar test cases for other implementations
}
I was looking at this topic:
java Access parent method from imported child class
But I'm still not sure the proper terminology for what I'm trying to do.
I have an Instance of Test and I want to call a method from the "parent" that created the instance.
public class Main {
public Main {
Test test1 = new Test();
}
public void showMessage(String message) {
System.out.println(message);
}
}
public class Test {
public Test {
//how do I call Main.showMessage("test is running")?
}
}
The answer in the topic I listed above was:
Assuming the "parent" is a class you're extending and the method you're calling is NOT static, the following should do the trick:
super.toggleVisibility();
If it's a static method - it's even Simpler:
Main.showMessage();
The issue:
I'm pretty sure I can't use super() cause I'm not extending a class. And I'm not sure if Main.showMessage(); will work because I haven't referenced the parent Main within the Test class.
You can pass an instance of Main into Test, and I'd use an interface to help decouple things:
public class Main implements Parent {
public Main() {
Test2 test2 = new Test2(this);
}
public void showMessage(String message) {
System.out.println(message);
}
public static void main(String[] args) {
new Main();
}
}
interface Parent {
void showMessage(String message);
}
class Test2 {
public Test2(Parent parent) {
parent.showMessage("I am running from in Test");
}
}
Create an instance of the desired class and call the desired method:
public class Test {
public Test() {
//how do I call Main.showMessage("test is running")?
Main main = new Main();
main.showMessage("test is running");
}
}
As noted by #BrianRoach, by your current code, this will generate a StackOverflowError since it is an infinite loop (Main instance that creates a Test instance in its constructor that creates a Test instance in its constructor ...)
So, another option may be passing a Main class instance to Test constructor:
public class Test {
public Test(Main main) {
main.showMessage("test is running");
}
}
Then, in Main constructor:
public Main() {
Test test1 = new Test(this);
}
I have a parent class like
class A{
//Constructors only called by builder.
public static class builder{
//builder code.
}
}
Class B Extends ClassA{
//constrctor
}
Now if i do in my test
final classA dempClassA = new ClassB("parameters here");
how can i call the builder now..?
Sorry guys the builder is a class...My mistake.
If I understand well what you're trying to say, you have the following situation:
public class ClassA {
// Constructors only called by builder.
public static class Builder {
// builder code.
public static void hello() {
System.out.println("Hello");
}
public void hello1() {
System.out.println("Hello1");
}
}
}
And you access it this way:
class ClassB extends ClassA {
public static void main(String[] args) {
ClassA.Builder.hello();
ClassA.Builder builder = new Builder();
builder.hello1();
}
}
If you want to call that method from outside the A class then it shouldn't be private.
If you just want it to be part of the B creation process then you should do something like this:
class B extends A {
public B() {
super(); // invokes A's constructor
}
}
class A {
public A(){
// use builder() here
}
}
Make ClassA's builder method protected (rather than private), so they're visible to ClassB, then use an anonymous class to call it, like this:
ClassA tempClassA = new ClassB("parameters here") {
{
// This block is called during construction
builder();
}
};
Since the builder (is that a class btw? or is the return type missing?) is static, you'd call it like A.builder(). And for it to be visible, you shouldn't make it private :)
Edit: since it is a class, you have several possibilities:
if you need a new instance call new A.builder(...)
if builder provides static methods (in which case the question would be why this is a class) call A.builder.someStaticMethod(...)
For example,
public class A {
public static int f() { return 1; }
}
public class B extends A {
public static long f() { return 100L; }
}
Unfortunately B.f() couldn't be compiled because B.f() tries to override A.f(), and so the name clashes because the return types aren't compatible.
I'm weired what's purpose to override a static method? Any use case? Can I just hide away A.f() in class B?
Actual usage:
class EntityDTO {
public static List<EntityDTO> marshal(Collection<? extends Entity> entities) {
...
}
}
class BookDTO extends EntityDTO {
public static List<BookDTO> marshal(Collection<? extends Book> books) {
...
}
}
Strictly speaking, static methods can not be overridden. Method overriding is exclusively a feature of object polymorphism, and static methods doesn't belong to any object but the class itself.
Having clarified that, you should not make any of your methods static. That would solve your problem in hand, at least. As the method arguments are different, it will not be considered as overriding, but overloading.
static methods are not overriden...But it is called method hiding. The benefits of using the same method name and parameters are just like any other method overriding benefits
static method can not be overridden.
Notice: your B.f() should return int rather than long to pass compile.
I can't think of a use case where overriding static functions (in Java) can be useful, but if you ever absolutely must achieve it, here's how:
import java.lang.reflect.Method;
class A {
public static void callOut() {
System.out.println("A.callOut");
}
}
public class B extends A {
public static void callOut() {
System.out.println("B.callOut");
}
public static void main(String[] args) throws Exception
{
A a = new A();
A b = new B();
Method aM = a.getClass().getMethod("callOut");
Method bM = b.getClass().getMethod("callOut");
aM.invoke(null); // prints A.callOut
bM.invoke(null); // prints B.callOut
}
}
Maybe you need to rethink you design, if you have a need to override the marshal method, then it shouldn't be static in the first place.
I'm think perhaps there is not a way to do this, but I thought it worth asking. I want to do something like the following:
public class Super {
public static String print() { System.out.println(new Super().getClass().getSimpleName()); }
public Super() {}
}
public class Subclass extends Super {
public Subclass() {}
public void main(String[] args) {
Super.print();
Subclass.print();
}
}
My hope is to get the Super.print() to show "Super" and Subclass.print() to show "Subclass". I don't see how to do this from a static context however. Thanks for the help.
I'm well aware that I can do this without static methods, and that I can pass a class into each method call. I don't want to do that as that requires redefining several static methods on many subclasses.
You can simply define a separate Subclass.print() method with the desired implementation. Static methods are class scoped, so every subclass can have its own implementation.
public class Subclass {
public Subclass() {}
public static String print() {
System.out.println(Subclass.class.getSimpleName());
}
public void main(String[] args) {
Super.print();
Subclass.print();
}
}
Note that your code can be somewhat simplified - Super.class suffices instead of new Super().getClass().
Also note, that static methods are not polymorphic - Super.print() and Subclass.print() will always call the method in the respective class. This is why they are bound to a class, not an object.
If you have a large class hierarchy, you may end up with a lot of duplicated code by implementing a separate static print() in each. Instead, you could define a single non-static method to do the job:
public abstract class Super {
public final String print() {
System.out.println(this.getClass().getSimpleName());
}
...
}
Note that this method does not even need to be polymorphic - this.getClass() will always return the actual subclass token.
Note also that I declared Super as abstract - this is (almost always) good practice to follow with base classes.
You can do this with out using static methods
public class Parent {
public print(){
System.err.println(this.getSimpleName());
}
}
public class Child extends Parent {
public void main(String[] args) {
Parent p = new Parent();
p.print();
Child c = new Child();
c.print();
}
}