So I have custom class that looks like this:
public class Cell {
protected boolean wasActive;
public Cell() {
this.wasActive = false;
}
public boolean getPreviousActiveState() {
return this.wasActive;
}
public void setPreviousActiveState(boolean previousActiveState) {
this.wasActive = previousActiveState;
}
}
Now I am writing another class here I need to call the above getPreviousActiveState() method:
public class Synapse<Cell> {
private Cell cell;
// some other methods... like isConnected
public boolean getPreviousActiveState() {
this.cell.getPreviousActiveState; // <= CAN'T BE CALLED. WHY?
}
}
I know the problem has to do with the fact that I declared the class:
public class Synapse<Cell>
but I did this so that only a Synapse can only contain a subclass of Cell. For example I also have implemented a VisionCell, AudioCell, and Neuron class that all extend Cell. Was this use of generics unneccesary? If so, when should I use generics? Thanks!
Defining a type parameter called Cell means is creating some confusion. Let's rename it to T, and also add the pair of missing parenthesis to the this.cell.getPreviousActiveState call:
class Synapse<T> {
private T cell;
// some other methods... like isConnected
public boolean getPreviousActiveState() {
return this.cell.getPreviousActiveState(); // <= CAN'T BE CALLED. WHY?
}
}
The error that you now get is:
The method getPreviousActiveState() is undefined for the type T
Which is the compiler's way of telling you that no where in the code it guaranteed that type parameter T has a getPreviousActiveState() method. Note that Java generic are not like C++ templates: the generic class is compiled once independently of any calling site. In other words: the compiler does not check this class w.r.t to any particular instantiation, but rather it checks that it makes sense on its own.
In order to guarantee that T has a getPreviousActiveState() all you need to do is to specify an upper bound on T that defines this method. We can use Cell itself:
class Synapse<T extends Cell> {
private T cell;
// some other methods... like isConnected
public boolean getPreviousActiveState() {
return this.cell.getPreviousActiveState(); // <= Compiles!
}
}
Of course, you can make the code more versatile by introducing an interface defining the method(s) you're interested in and using this interface as the upper bound. You will also have to make Cell implement this interface:
interface ActiveStateProvider {
public boolean getPreviousActiveState();
}
class Cell implements ActiveStateProvider {
protected boolean wasActive;
public Cell() {
this.wasActive = false;
}
public boolean getPreviousActiveState() {
return this.wasActive;
}
public void setPreviousActiveState(boolean previousActiveState) {
this.wasActive = previousActiveState;
}
}
class Synapse<T extends ActiveStateProvider> {
private T cell;
// some other methods... like isConnected
public boolean getPreviousActiveState() {
return this.cell.getPreviousActiveState(); // <= Compiles!
}
}
Related
public interface Usable {
public boolean isUsed();
public void setAsUsed();
public void setAsNotUsed();
}
My question is:
The Book class has to implement the Usable interface and join the interface methods with status instance variable either to set the status of the as used or to set the status of the as not used or to return the current value of used instance variable.
I dont really understand how exactly to do what the question is asking.
Well for a start you will need
public class Book implements Usable {
and then because you have done this you will need to implement these methods which hint to the need for a boolean field called used
private boolean used;
public boolean isUsed() {
return used;
}
and hence
public void setAsUsed(used = true);
public void setAsNotUsed(used = false);
You have to create a class that implements Usable by defining the methods (in your case getters and setters) that are declared there:
public class Book implements Usable {
// Initialization
private boolean used = false;
// Getter
public boolean isUsed() {
return this.used;
}
// Setters
public void setAsUsed() {
this.used = true;
}
public void setAsNotUsed() {
this.used = false;
}
}
I assume this is your book class:
public class Book {
private boolean used;
// other things
}
To implement the interface, first you need to
public class Book implements Usable {
//...
Then, implement the methods one by one. We can guess what each one does by looking at the name and signature. isUsed returns a boolean so it probably should return whether the book is used. Let's implement this:
public boolean isUsed() {
return used;
}
setAsUsed, well, set the book as used:
public void setAsUsed() {
used = true;
}
And setAsNotUsed does what it says on the lid as well:
public void setAsNotUsed() {
used = false;
}
public class Flight{
private int flying = 0;
public boolean fly() {
flying = 1;
return isFlying();
}
private isFlying(){
return flying > 0;
}
}
public class CargoFlight extends Flight{
public boolean startFlight(int passengers)
if (passengers <= 0){
return false;
}
return fly(); // Want to be able to do this
}
}
public class Airport{
public static void main(){
CargoFlight f1 = new CargoFlight();
f1.fly(); // Don't want to be able to do this
}
}
f1 has the property fly(), is there any way to restrict it such that the method fly() can be called inside the body of the classes extending Flight (like CargoFlight here), but cannot be called using the instances of the subclasses (like f1)? I have added comments to the code to make it clear.
The nearest access specifier to what you want is protected. However, protected members are still always accessible to other classes in the same package, so it won't prevent access from your Airport class.
If you really need the subclass to block access to the method except to the subclass, then you can override it in the subclass to always throw an exception, then use super to invoke the original method:
public class Flight {
private int flying = 0;
protected boolean fly() {
flying = 1;
return isFlying();
}
private boolean isFlying() {
return flying > 0;
}
}
public class CargoFlight extends Flight {
#Override
protected boolean fly() {
throw new IllegalAccessError();
}
public boolean startFlight(int passengers) {
if (passengers <= 0) {
throw new IllegalArgumentException();
}
return super.fly();
}
}
The flaw with any solution though, is that it violates the Liskov substitution principle. A CargoFlight is no longer a proper instance of Flight because it doesn't have the normal fly method that other Flights have. If you intend fly only to be called by subclasses and never directly, then it's okay (although you should document that rule in the method Javadoc), but it still leaves you without the nicety of having a polymorphic method to call to tell generic Flights to fly.
A nicer solution, if it can fit with your design, would be to have fly and startFlight be the same method (that means same name and same arguments, and the same return type or a subtype), so then the subclass method could simply override the base implementation. The only method outside callers would see is fly. That means that your passengers argument either needs to be part of the base method Flight.fly too, or, remove it from both method implementations and make it into a separate property setPassengers for those subclasses that need it:
public class CargoFlight extends Flight {
private int passengers = 0;
public void setPassengers(int p) {
passengers = p;
}
#Override
public boolean fly() {
if (passengers <= 0) {
throw new IllegalStateException(); // or whichever
}
return super.fly();
}
}
I'm looking for a way to be able to define a method for each enum instance. We all know about the code construction at the bottom of this page.
The difference I'm looking for is to be able to define one or more abstract methods for each enum in a separate file that is verified compile-time. Meaning if someone were to add another enum instance I would get a compile-time error and not a run-time error which is what I get with the construction at the bottom of this page.
The reason for the request is that in some code I'm looking at there are many methods that should be defined per enum but are really unrelated to the enum definition so I'd like to place them in separate files but not lose the benefits of the "standard" way of solving this.
public enum MyEnum {
X {
public void calc(Outer o) {
// do something
}
},
Y {
public void calc(Outer o) {
// do something
}
};
// abstract method
abstract void calc(Outer o);
}
Consider the folowing code:
interface Delegate{
void calc();
}
enum TestEnum {
EnumValue1(new Delegate() {
#Override
public void calc() {
}
}),
EnumValue2(new Delegate() {
#Override
public void calc() {
}
});
private Delegate delegate;
TestEnum(Delegate d){
this.delegate = d;
}
public Delegate getDelegate() {
return delegate;
}
}
public class Test {
public static void main() {
TestEnum.EnumValue1.getDelegate().calc();
TestEnum.EnumValue2.getDelegate().calc();
}
}
You cannot define methods for classes outside of a class!
You could define a callback interface that each enum instance had to have an instance of:
public interface MyEnumCallback {
doStuff(final Outer o)
}
Then your enum would look something like
public enum MyEnum {
X(new XCallback()),
Y(new YCallbaxk());
private final MyEnumCallback callback;
public MyEnum(final MyEnumCallback callback) {
this.callback = callback;
}
public <Whatever> call(final Outer o) {
callback.doStuff(o);
}
}
This separates your Enum from the methods as you wanted - it would also throw a compile time error if someone didn't provide an implementation of MyEnumCallback to the constructor of the Enum instance.
Is it possible to modify the return value of an abstract method during runtime?
For instance:
public abstract class Task {
public abstract boolean validate();
public void setValidate(boolean b) {
/* modify the return value of 'validate' method */
}
}
Why not just have a boolean field in Task, have validate return the value of that field, and have setValidate change that value?
public abstract class Task {
private boolean isValid;
public boolean validate() { return isValid; }
public void setValidate(boolean b) { isValid = b; }
}
Alas, if only you could (easily, anyway). But there is a workaround if you can modify the abstract class and subclasses. Make subclasses implement a protected method instead, then make it so that your validate() method checks the value of the validate before validating. You should probably also make validate() a final method, as I have in the example, so that subclasses can't change it to not check the variable. This is up to you, of course.
Here's the code for the workaround:
public abstract class Task {
private boolean validate = true;
public final boolean validate() {
// Assumes that no validation means validation always passes
return validate ? validateImpl() : true;
}
protected abstract boolean validateImpl();
public void setValidate(boolean validate) {
this.validate = validate;
}
}
Not sure how to title this...
So I've got three child classes of Event: WeightEvent, TimedEvent, RepEvent. Through whatever means, I get an object of one of the children. Now I want to send that child event to a method in another object so it can pull the data from it with the getSavedEvents() method. The method only exists in the children since pulling the data is specific to the type of event.
I started with
public void setEvent(Event e) {
but that cast my child object to an Event (parent) object.
Is there any way around this short of writing three different methods. One each for the children?
public void setEvent(WeightEvent e) {
public void setEvent(TimedEvent e) {
public void setEvent(RepEvent e) {
Thanks for any advice.
-John
Even though the reference is cast, it doesn't change the type of the actual object. When you pass the reference on, it will still be a reference to an instance of the child object. Normally this would be enough, with appropriate abstract methods in the parent type if necessary.
However, if the methods you want are specific to the types of the children and you can't come up with an appropriate abstraction which all of them can implement generically, then either you've got to use instanceof within your setEvent code or you do have to overload your method... because you're going to have to call different bits of code depending on the exact type of the event.
This is all a bit vague because we can't see any of your code except a couple of method signatures. If you could give us more details about what you're trying to do, particularly in terms of what setEvent needs to achieve and what the different methods in the child classes are, we may be able to help more.
Instead of switching on the type you should call a method on the event that's defined differently for each type of event type. This is called the Template method pattern. (It has nothing to do with C++ templates, BTW)
Using this pattern, your EventTable class becomes something like this:
public class EventTable {
public void setEvent(Event e) {
int x = 0;
columns = e.getFields();
Event[] savedEvents = e.getSavedEvents();
for(Event ev : savedEvents) {
tempdata[x] = ev.getTempData();
x++;
}
}
}
Note that the entire switch has been replaced with a single call to getTempData(). This method is then abstract in Event, just like getSavedEvents:
public abstract class Event {
public Date getDate() { return(_date); }
public abstract Event[] getSavedEvents();
public abstract int[] getTempData();
public int[] getFormattedDate() {
...
}
Then you define the getTempData() method in each subclass. For example:
public class WeightEvent extends Event {
public int getWeight() { return(_weight); }
public int getReps() { return(_reps); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getWeight(),
getReps()
};
}
}
public class TimedEvent extends Event {
public String getTimeInHMS() { return(_timeString); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getTimeInHMS()
};
}
}
public class RepEvent extends Event {
public int getReps() { return(_reps); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getReps()
};
}
}
You could use generics to do this.
Define the Event class as follows:
public abstract class Event<T extends Event> {
public abstract void setEvent(T e);
}
This defines a class that expects to be created with any type that extends Event.
Then in your child classes you implement something like this using the child class as the generic type:
class WeightEvent extends Event<WeightEvent>
{
#Override
public void setEvent(WeightEvent e) {
...
}
}
I think your probem is calling getSavedEvents() when having an Event variable.
If so, add an abstract getSavedEvents() method to Event, which must also be declared abstract :
public abstract class Event {
public abstract Events getSavedEvents();
...
}
since Eventis abstract you can not create an instance of it; it must be subclassed to be used. If that is a problem, throw an Exception or do anything reasonable for your application (nothing at all, just return null) in Event.getSavedEvents():
public class Event {
public Events getSavedEvents() {
throw new UnsupportedOperationException("must be called in a child class");
// OR return null;
...
}
now you can call the getSavedEvents() method in your other object:
public class OtherObject {
private Event event;
public void setEvent(Event e) {
event = e;
...
Events events = event.getSavesEvents();
the method implemented by the real class of e will be used, e.g. if e is a TimedEvent, the method in that class will be called.
You could abstract the problem out behind an interface
interface IEvent
{
abstract public void doSomething();
}
Then have all your event classes implement it, e.g.
class WeightedEvent implements IEvent
{
public void doSomething()
{
// do something
}
}
Then you only need a single method and don't need to do any type checking
public void setEvent(IEvent e)
{
e.doSomething();
}
HTH
May be you can use a Visitor pattern.
Using abstract helped with the getSavedEvents() method, since all of the children implement that method.
Here's the code for setEvent():
public class EventTable {
public void setEvent(Event e) {
int x = 0;
int type = e.getEventType();
columns = e.getFields();
Event[] savedEvents = e.getSavedEvents();
for(Event ev : savedEvents) {
tempdata[x][0] = ev.getFormattedDate()[0];
switch(type) {
case EVENTTYPE.WEIGHT:
tempdata[x][1] = ev.getWeight();
tempdata[x][2] = ev.getReps();
break;
case EVENTTYPE.TIMED:
tempdata[x][1] = ev.getTimeInHMS();
break;
case EVENTTYPE.REP:
tempdata[x][1] = ev.getReps();
break;
}
x++;
}
}
}
This code works after I added "abstract" to the Event class and defined an abstract method called getSavedEvents().
The next problem is the getWeight(), getReps() and getTimeInHMS() methods. They are specific to the type of child event and again don't exist in the parent Event class. If I make them abstract in Event, now I have to define them in each child, even though getReps() has no context for a TimedEvent.
public class Event {
public Date getDate() { return(_date); }
}
public class WeightEvent extends Event {
public int getWeight() { return(_weight); }
public int getReps() { return(_reps); }
}
public class TimedEvent extends Event {
public String getTimeInHMS() { return(_timeString); }
}
public class RepEvent extends Event {
public int getReps() { return(_reps); }
}
Abbreviated code, obviously. WeightEvents have a date, weight and reps associated with them. TimedEvents have a date and length of time associated with them. RepEvents have a date and number of reps associated to them. The date methods are all in the parent since they are common across events.
If I don't make getWeight(), getReps() abstract and only declare them in the child where they are relevant, here's the error I get from EventTable in the above copied setEvent() method:
EventTable.java:124: cannot find symbol
symbol : method getWeight()
location: class Event
tempdata[x][1] = ev.getWeight();
-John
You could cast the Event e object to the child classes -- I think the instanceof operator in Java will help you.