I am running into the trouble of extending/altering private methods in subclasses. For instance, I am creating a mock object that inherits from a super class in order to be used in testing.
Here is an example of the code from the parent class that I would like to alter:
private void build(int skill) {
// switch screen
state = Constants.STATE_GENERATING;
percentdone = 0;
notifyViewerRedraw() ;
// select generation method
switch(method){
case 1 : mazebuilder = new MazeBuilderPrim(); // generate with Prim's algorithm
break ;
case 0: // generate with Falstad's original algorithm (0 and default), note the missing break statement
default : mazebuilder = new MazeBuilder();
break ;
}
}
I know that private methods cannot be overwritten in subclasses. So therefore I should create a new method of the same signature. Would I also have to recreate all the private variables in this class too? But if I do that, I am unsure if that would change the behavior to be different from the parent class since the I know that space is actually reserved for private variables from the parent class in the subclass. Therefore, I would have duplicate private variables. I don't know what the best way is to approach this.
If you find the need to override a method in a subclass, perhaps the logic that method is responsible for is abstract enough to warrant a public or protected method.
Consider the design of the Strategy Pattern. Basically, there shouldn't be a need to override a private method, because those methods should be reserved for things outside your interface and only specific to that particular concrete class.
Something as integral and specific as build() to me sounds like it belongs as a protected method which your highest superclass may use at some point during construction but which shouldn't be called externally. Of course, if it's safe to call build() as many times as necessary (idempotent), like a render() method might be in a game character class, then it should be safe to make it public and document what your expectations are of its implementation.
Try using mocking API, for example Jmockit .
Using it, will save you a lot of trouble doing hand mocks, like in your case extending class with private methods! Good luck.
Im not sure how your program works overall but it might be worth you looking into abstract classes and methods if you want all of the base classes to share the same methods(?)
You can call super() in the subclasses method which will call the superclasses method and then make the extra changes you need in the subclasses method.
Edit: Read the original question wrong. If a method has functionality in the superclass and you want to extend or alter it, you shouldn't set it to private. Protected is probably the best bet in your case, as it allows subclasses to extend it using super() or just override it.
Related
I have a class, lets say CargoShip, which is a derived class of 'Starcraft', which implements the interface IStarcraft.
This is the function that should return the count (number of instances) of every ship:
public static void printInstanceNumberPerClass (ArrayList<ISpacecraft> fleet){}
There's a solution which I thought of and I'm sure it will work, declaring 'getCount()' in ISpacecraft, then overriding it in each SpaceCraft ship (I have 4 ships), and just iterating through everyone of them, polymorphism.
Fine, I got that. but because the function is static (yes, I know we dont need to create an object to use it) I thought it might tell me something different. What do I mean by that? Is it possible to create 'static count = 0' instead, in every ship, and somehow access it?
The question is then, how can I access that static field when I get an arraylist of ISpacecraft objects?
Polymorphism doesn't work with static methods, method resolution is very different. For virtual methods on an instance the code may be referring to the object with a variable typed as a superclass or interface, and calling a method is resolved at runtime without your application code needing to know the exact concrete type. For static methods you call it on a specific class and if the method isn't found then it's called on a superclass. Your code has to start with some subclass and resolution works up the hierarchy from there. For static methods you can't not know a low-level class to call the method on, the way you can with instance methods on objects. You can't have the level of abstraction you take for granted with objects.
The comment by markspace provides a much better alternative. Use static methods for stateless functions like java.lang.Math.
Every Time i create a new class i wonder what is the best way to create a constructor. If i use the default constructor made in IntelliJ it would create a constructor like example A. But at school we learn to use methode B.
Is there some big difference between A and B.
Is there some preferred way or is just a programmers choice ?
Example A:
public Model(int modelNumber) {
this.modelNumber = modelNumber;
}
Example B
public Model(int modelNumber) {
setModelNumber(modelNumber);
}
public void setModelNumber(int modelNumber) {
this.modelNumber = modelNumber;
}
Unless your class is marked as final, example B in its current form is definitely wrong.
The principle you need to follow is that you mustn't call overrideable methods from your constructor. If you don't obey that rule, you can't maintain class invariants: you can't guarantee that a subclass doesn't change what setModelNumber() does and you can end up with a modelNumber field that hasn't been initialised to the expected value.
Failing to follow this principle could carry other, less obvious, but no less damaging consequences too.
And for that reason it's usually preferable that you set the fields directly from the constructor. Not only that, in the case of final fields, that is your only option.
Example A is more preferred, The moment you create your object you need to call the constructor to initialize values of your class members, setters and getters are used for other functions in your code to make use of the same members! It becomes extremely important to consider Example A. You can't do the calling setter if you want to inherit this class. You cannot make your class non inheritable.
So the answer is NO! Don't use Example B!Cheers!
I definitely agree with the idea of
you mustn't call overrideable methods from your constructor"
as biziclop user said, so try to avoid the B example! In addition, B example is more expensive than the A. Think about the processor. Instead of going directly to the class attribute modelNumber it has to go to setModelNumber method first. Once there, it has to setup the modelNumber with the specified one. In the end, both examples do the same, but A is more direct and efficient.
I have a class called Base which has a method called execute(). There are about 100 classes which derive from this base class and provide their own implementation of execute(). Now, I have some common logic which I want to put in Base.SomeMethod(). This method needs to be called at the end of execute(). My question whether it is possible to call this without changing each and every derived class's execute() method?
public class Base {
public final void execute() {
doExecute();
someMethod();
}
protected abstract void doExecute();
public void someMethod() {
}
}
This solution prevents the super code smell.
Yes, but you have to change the callers then. Callers will have to call a doExecute() (find a better name for it though) method, which you define in your base class as final, and which calls execute(), then the common code.
Another option is aspect-oriented programming, but I wouldn't recommend it for this purpose, that is, to "hack" code.
The question is: why is changing the name of a method in a 100 or so classes such a problem? It's a click of the mouse with an IDE.
Not that I'm aware of. Next time you should consider that you might want to add some common action for all extended classes, and call for super.execute()!
Only by using something that instruments your code; this isn't possible with pure Java.
Let me state your problem as i understand : Animal class has Breath() method which has implementation and due to inheritance all the subclasses has this member and unless there is very different way of breathing nobody will override.
Now at the end of Breath method you want to call CloseEyes() method of animal class and may be that is true that some or all of the subclasses overrides CloseEyes() method.
So your problem : Everytime any animal breath you want to them to CloseEyes but from Animal class and not from the derived classes.
If there are already CloseEyes() methods in many derived classes then you are actually doing something wrong in calling base class's CloseEyes().
If you still want only base class's method to be called then why do you need same method name- you just say AnimalEyeClose() , make it private and have it in Animal class.
I have been challenged by a design issue which I will try to describe below.
Suppose that a class, call it A, has a constructor with a bunch of parameters. Since it is tiring and dirty to write all those parameters in each instantiation, I have written another class, call it StyleSheetA, which encapsulates all those parameters and is the only parameter to the constructor of A. In this way, I can prepare some default StyleSheetA templates to be used later, and if it is needed, I can modify them.
And at this point, I need to extend A. Suppose B extends A. B will have its own stylesheet, namely StyleSheetB. I think it will be appropriate that StyleSheetB extends StyleSheetA, so with one stylesheet parameter, constructor of B can also construct its super class A. But I am afraid of the possibility that this design may have flaws. For example what if I decide to add a getter/setter for the stylesheet? Is there a novel way to handle all these situations? Am I in the wrong way? For those who are confused, I attach some code here:
class A
{
StyleSheetA ss;
A(StyleSheetA ss)
{
this.ss = ss;
// Do some stuff with ingredients of styleSheet
}
}
class StyleSheetA
{
int n1;
int n2;
// :
// :
int n100;
}
class B extends A
{
B(StyleSheetB ss)
{
super(ss);
// Do some stuff with ingredients of styleSheet
}
}
class StyleSheetB extends StyleSheetA
{
int n101;
int n102;
// :
// :
int n200;
}
Thank you for any help or suggestions, also any of your critics will be appreciated.
Edit: I am developing in java me so there is no generics support.
It seems to me that you are only moving the problem of having too many parameters from class A to class StyleSheetA.
To illustrate my point, think of this question: How would you instantiate StyleSheetA? Probably using a constructor that accepts all these parameters, anyway. The only benefit this design may give you is if you have a same set of parameter values encapsulated by an object of StyleSheetA which you will reuse among multiple instances of A. If so, bear in mind that although you'd have different instances of A they would share the same parameters, so it isn't a good choice.
What I could recommend you is to try to refactor your class A itself. Try to break it up into smaller classes. If nesseccary, try to create subclasses to avoid conditional branches, etc.
Now, I don't know how your class A looks like, but maybe if you do so you'll have several classes, each with its own set of parameters. And if any of the parameters is a discriminator (meaning that it determines the class "type") you will be able to get rid of it, just by using subclasses, and relying on built in type system to do it instead.
Have you considered using an IoC container, like StructureMap, to manage your constructor dependencies? That might make a lot of this stuff easier.
A thoughts on the getter and setter issue:
The constructor in 'B' implies that the additional parameters (n101+) are necessary for the operation of the class. If you were just extending the class with a full parameter list, you would have getters and setters for n101...n200 in B and n1...n100 in A. This suggests perhaps not having StylesheetB extend StylesheetA, but rather have the constructor to class B be B(StyleSheetA,StyleSheetB), this way you can have a setter in class A for it's parameters, have that inherited and also put one in B for StylesheetB.
I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.