Patterns for implementing common class behavior through a class hierarchy - java

I have a Java class hierarchy for which a sub-tree of the hierarchy implements the same static data and methods. I cannot inherit because they are all statics, but it smells to me when I am cutting and pasting the same bits of code from one class to the next. One thing I am considering is to put the common bits in a class, and then give each of the sub-classes a static instance of that class. Anyone have a thought about a better approach to this situation (without using generics)?

My solution
I have created a separate class which implements the functionality which is troubling me.
I give every class in the hierarchy their own static instance. Works a treat.

That's sounds about right. Just have a class of statics that are immutable and reference them directly in the classes that need it (call is Constants or something like that. You shouldn't need to create an instance to refer to static objects on a class though - they're static so they "should just exist".
i.e.
public class MyConstants{
public static final String MyConstantValue1 = "Billy";
public static final String MyConstantValue2 = "Sally";
}
public class SomeClass{
public void something(){
System.out.println(MyConstants.MyConstantValue1);
}
}
public class SomeSubClass extends SomeClass{
#override
public void something(){
System.out.println(MyConstants.MyConstantValue2);
}
}

Related

Why my interface methods cannot be overridden?

I'm trying to implement interface like this :
public interface Human{
void talk();
}
public class Ame implements Human{
public static void talk(){
System.out.println("Speak English");
}
}
public class Chin implements Human{
public static void talk(){
System.out.println("Speak Chinese");
}
}
public class test {
public static void main(String[] args){
Chin c = new Chin();
c.talk();
Ame a = new Ame();
a.talk();
}
}
But it shows errors :Ame and Chin talk() cannot implement Human talk().
Methods is overridden as static .
Please tell me why this heppened and how to fix this error.
Static methods are part of Class and not Objects. Overriding is concept of polymorphism, ie, a method associated with an instance can have multiple behaviour.
Static methods are not associated with instance and polymorphism cannot be applied.
When you declare a method as static, it belongs to the class as a whole and not a specific instance. The methods of an interface cannot be static in Java. When you implement an interface, you are expected to provide an instance method for the abstract methods of the interface. When you use a static method, your static method tries to hide the instance method of the same name. But this would violate the rules to be followed while implementing an interface. Thus we cannot make the interface methods as static in the implementing class.
You cannot reference a non-static interface from a static method this way. In essence, a static method is one that can be accessed directly without recreating a local duplicate object, but its values cannot be modified in the same way. Really, the solution to this problem is quite simple. Remove the static modifier from the overriding talk() methods

Referencing a variable declared in abstract class from inherited class

I'm currently reading a book on design patterns which is written towards java, but would like to code examples in both Java and C#. Right now I'm trying to implement the strategy pattern in C#, and while I've found a lot of examples online, my current problem is something that I want to figure out the most.
In the Java example I have an abstract class and then a class that extends that abstract class. In the abstract class I declare, but don't instantiate, variables of an interface, which are then instantiated in the extended class.
Interface:
public interface MathStuff{
public void add();
}
Abstract:
public abstract class Math{
MathStuff mathStuff;
public Math(){}
public void addStuff(){
mathStuff.add();
}
}
Extended Class:
public class DoStuffWithMath extends Math{
public DoStuffWithMath(){
mathStuff = new RandomClass();
}
}
Now I would really like to replicate this in C#. The C# code is essentially the same. I have an interface, an abstract class, and a class that I assume is extending the abstract class. I am not as familiar with C#. That class looks like this.
class DoStuffWithMath : Math{
public DoStuffWithMath(){
mathStuff = new RandomClass();
}
}
The problem with the C# code is where i try to say "mathStuff = new RandomClass()". Any help or reading material would be appreciate.
Explicitly adding protected would fix the issue (to override default private access):
public abstract class Math{
protected MathStuff mathStuff;
public Math(){}
public void addStuff(){
mathStuff.add();
}
}
Note that depending on your needs either passing mathStuff as constructor of base class or using property instead of field would be better solution.

How to see methods from other class

I got a class where I made multiple methods, but I want to put some of them in another class, since they do other things. How can I have my first class still use my methods?
Class A had 15 private static methods(they are static since they just return values and I don't need to define an object)
I created Class B in the same package and when moving 5 methods in it, the main function from A will not detect them when used.
Your problem is the visibility. private means only the wrapping class can see these methods.
Set the visibility to default (if both classes are in the same package) or public if they're in different packages.
For example, classes A and B are in same package:
// A.java
public class A {
static void oneMethod();
}
// B.java
public class B {
private static void anotherMethod() {
A.oneMethod();
}
}
or in different packages:
// A.java
public class A {
public static void oneMethod();
}
// B.java
public class B {
private static void anotherMethod() {
A.oneMethod();
}
}
That's because you've defined the methods as private. You should define them as package protected (remove the 'private' part), or public (replace private with public).
Having said that: having a class with 15 private static methods is so uncommon that I'd add the label 'bad practice' to it. Can you share your code, so that it's more clear what these methods are doing? Unless you are creating a utility class, say StringUtils, I'm pretty sure there's a small chance you need any static methods at all.

How to define nested static classes with static methods, inherited from a nested interface in Java?

I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.

Why use Static Nested Classes in Java?

I am new to java and have been scratching my head understanding some its concepts.
I am following the tutorial Java tutorial. However, I cannot find the usefulness of using Static Nested Classes. I mean I think I need some good examples as to why I should want to use it. Can someone provided me some codes as examples so I can understand it better?
thax
The benefit of a static nested class over an "ordinary" class is that you can use it to reflect the relationship between two classes.
For example in the JDK there is java.util.Map and java.util.Map.Entry.
java.util.Map.Entry is declared as a public static interface and doing it this way clearly signposts its relationship to Map. It could have been defined as java.util.MapEntry but doing it as a static nested interface makes it clear that it has a strong relationship to Map.
So you'd probably only use static nested class when the nested class would only ever be used in the context of its parent.
The following example might not be for a Java beginner but one nice example of static nested class is when you want to use the Builder pattern to construct immutable objects of the outer class. The static nested class is allowed to access private members of the outer class thus constructing objects of the outer class although it has a private constructor and initializing private fields of the outer class.
E.g.
public class SomeClass {
private int someField;
private int someOtherField;
private SomeClass()
{}
public static class SomeBuilder {
private int someField;
private int someOtherField;
public SomeBuilder setSomeField(int someField)
{
this.someField = someField;
return this;
}
public SomeBuilder setSomeOtherField(int someOtherField) {
this.someOtherField = someOtherField;
return this;
}
public SomeClass build() throws ValidationException
{
validateFields();
SomeClass someClass = new SomeClass();
someClass.someField = someField;
someClass.someOtherField = someOtherField;
return someClass;
}
private void validateFields() throws ValidationException {
//Validate fields
}
}
public int getSomeField() {
return someField;
}
public int getSomeOtherField() {
return someOtherField;
}
}
Nested or inner class is just an ordinary class defined into other class. The reason to do this is typically to hide inner class from others, i.e. it is yet another level of encapsulation.
Inner class can be private, protected and public that mean exactly the same as for fields and methods.
If inner class is not private you can access it from outside too. Its name is OuterClass.InnnerClass. The nesting depth is not limited by Java specification, so inner class can have its own inner classes etc.
If inner class is not static it has yet another feature: ability to call outer's class methods and fields.
Inner class can be also anonymous. This is very useful for small callbacks, event handlers etc.
Hope this helps. Do not hesitate to ask other more concrete questions.
Another thing I should add is that if an inner class is not static, an instance of it will automatically have a reference to its parent class instance. You can reference it by using: NameOfOuterClass.this.
But if it is static, then it will not.
This, among other things, comes into play during GC (garbage collection).
Because, if an object of the inner class is not being GCed, then the outer class object it references will not be GCed either (in cases where the inner class was not static).

Categories