So, I am trying to learn how the interface classes in Java Work, and i'm really confused about it.
I wan't to make it like a method in a normal class file like this:
public class APIClass {
private int davs;
public int setInt(int dav) {
this.davs = dav;
return davs;
}
public int getInt() {
return davs;
}
}
Two methods. One that set's the int "davs", and one getting the int "davs".
What i wan't to do in the interface is something like that. I have seen in others interface files, that they have something like this:
public interface MyInterface {
public MyInterface setInt(int davs);
public MyInterface getInt();
}
EDIT:
My question is that i can't see what i can use the interface for? All i have seen use it, declare the same method in a new class file, and then they really don't need the interface file. So what is it for?
Interfaces in Java are meant as an abstraction. You're expected to use it strictly for deriving other classes. You don't declare any methods in it all.
So if you have an interface like this:
public interface MyInterface {
int setInt(int davs); // this should probably return void
int getInt();
}
And you implement it in a class like this:
public class APIClass implements MyInterface {
private int da;
public int setInt(int davs) {
// return da; <- this doesn't make a whole lot of sense
da = davs; // I assume you meant this
return da; // usually you don't return anything from a setter
}
public int getInt() {
return dada;
}
}
And another class like this:
public class SecondAPIClass implements MyInterface {
private int dada = 0;
public int setInt(int davs) { // note that you have to keep the same method signiture in all derived classes
dada = davs + 5;
return dada;
}
public int getInt() {
return da;
}
}
You can use the interface to group them both. This is an important part of object oriented design. It's usefulness is probably too long to explain in a simple StackOverflow question, but here's a simple example of its usefullness:
import java.util.ArrayList;
public static void main(String[] args)
{
APIClass first = new APIClass();
SecondAPIClass second = new SecondAPIClass();
first.setInt(20);
second.setInt(20);
ArrayList<MyInterface> list = new ArrayList<MyInterface>();
list.add(first);
list.add(second);
for(MyInterface item : list) {
System.out.println(item.getInt());
}
}
The output should be this:
20
25
This example might be more helpful:
Consider you have several vehicles. All vehicles can drive, but driving a boat is different from driving a car, or a helicopter. This is where interfaces are useful. You can declare what a Vehicle should do, without dictating how it should do it.
public interface Vehicle {
void drive();
}
So when you derive it in a class Car, you can state how you want this vehicle to drive.
public class Car implements Vehicle {
void drive() {
// drive like a car
}
}
Now boats are vehicles, and they can drive too, but driving a boat is much different than driving a car.
public class Boat implements Vehicle {
public void drive() {
// drive like a boat
}
}
In summary, interfaces are useful when you have an abstract concept in mind, where you know what derived objects should do but can't dictate how they do it.
Related
I wrote an easy interface-inheritance example to illustrate what I'm trying to do.
interface Fruit{
public void taste();
}
class Banana implements Fruit {
public String name = "Banana";
public void taste(){
System.out.println("yummy banana!");
}
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a"+ fruit.name + "!" );
// error: name cannot be resolved or is not a field
fruit.taste();
}
}
class exec {
public static void main(String[] args) {
Lunch<Banana> bananalunch = new Lunch<>;
bananalunch.fruit = new Banana();
bananalunch.tasteit();
}
}
So Banana and Strawberry are implementing Fruit. In the class Lunch I'm trying to call the fruit name and its function taste();
While calling the Function taste works just fine, i can't call the name (see: error in the comment)
Wanted Output:
I'm going to eat a Banana!
yummy banana!
Like I said, yummy banana works but the name can't be resolved. I tried to declare "public String name = "default""; in the Fruit interface. Then you can call it, but it will always say "default" and not the name in the actual class.
Is there a way to get a member of a generic Type that implements an interface?
P.S. I need to do it like this, of course this code was only for representation but I have a much larger more complicated code in which i encountered this problem- And I don't want to restructure it if not necessary.
Thank you in advance!
Your problem is caused by trying to access an instance member directly - fruit.name - instead of via a method - fruit.getName().
If you use a getter method, the correct method will be executed and return the required output.
That said, in this particular example it would make more sense to have a single getName() method in a base class, and a single _name variable in that base class, which is initialized to a different value based on the actual type of fruit class.
On the other hand, seeing that your Fruit is an interface rather than a base class, you can have each of the classes which implement that interface have a getName() method returning a different value.
For example:
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
would become:
class Strawberry implements Fruit {
public String getName () {
return "Strawberry";
}
public void taste() {
System.out.println("yummy strawberry!");
}
}
You would have to add getName() to the interface:
interface Fruit {
public String getName();
public void taste();
}
Finally, your Lunch class becomes:
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a "+ fruit.getName() + "!" );
fruit.taste();
}
}
Case, when class implements interface, means that object of this class can do something that described in interface.
For example, every plane shape has area. So we can determine interface:
interface PlaneShape {
int getArea();
}
Area of square is product of edges. And area of circle is product of
squared radius by pi number divided by 2. So:
class Square implements PlaneShape {
public int edge = 5;
public int getArea() {
return edge*edge;
}
}
class Circle implements PlaneShape {
public int radius = 5;
public int pi = 3.14;
public int getArea() {
return radius*radius*pi/2;
}
}
Interfaces use for abstraction. AreaCalculator operates with plane shapes, so it abstracts from any specific kind of plane shapes. AreaCalculator just knows that any shape can give him area value by executing method getArea(). AreaCalculator don't know anything about special shape fields, like edge or radius.
class AreaCalculator<S implemets PlaneShape> {
public S shape;
public int calculateArea() {
shape.getArea();
}
}
By this way, in your example,Lunch<Fruittype implements Fruit> class don't know anything about fruits inner names, it doesn't "see" this fields, it only can invocate method taste(). You need to add method getName() to interface, and implement it.
On the subject of name="default" in interface. It declared in context of interface and hasn't any relation to implementations.
I've inherited an abstract parent class with only a single child class, both in
separate files.
They're big and ugly. And they're no-longer structured correctly.
I'm going to refactor them to be much nicer - but as part of this I'd
first like to collapse them into a single class. I.e. to go from something like this:
public abstract class ParentClass implements SomeInterface {
ParenClass(SomeOtherClass v) {
aMember = v;
}
#NonNull final SomeOtherClass aMember;
abstract void doSomething();
// Several hundred lines of other functions and members.
}
public class ChildClass extends ParentClass {
ChildClass(AnotherClass v2) {
super(v2.getSomething());
this.childMember = v2.somethingElse();
}
#NonNull final SomeOtherClass aMember;
#Override void doSomething() {
//...
}
// Several hundred lines of other functions and members
}
To a merged version of both classes (Could actually be named like either
of the original classes though...)
public class MergedParentAndChild implements SomeInterface {
JustOneClass(AnotherClass v2) {
this.aMember = v2.getSomething();
this.childMember = v2.somethingElse();
}
void doSomething() {
//...
}
// Lots of other functions etc.
}
I've done this by hand using the "pull up" refactor on all members but it's time consuming as
it gets constructors wrong and has issues with final members and abstract functions etc.
Maybe eclipse probably has a quick way to do this directly in its lists of refactorings. I just can't seem to find it.
Is there a quick and easy way to do this?
Using the "pull up" refactor isn't as repetitive/painful as I'd initially thought. I'm going to borrow JClassic's example and modify it a little (to make it worse) and show what happens
Here's the original code.
public class Temp {
public static interface I1 {
public void interfaceFn1();
public void interfaceFn2();
}
public static abstract class A implements I1 {
int a;
public void foo(){
System.out.printf("%s In A a=%d\n", this, a);
}
#Override public void interfaceFn1() {
System.out.println("In A.interfaceFn1");
}
}
public static class AA extends A {
int aa;
#Override
public void foo(){
super.foo();
System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa);
}
#Override public void interfaceFn2() {
System.out.println("In A.interfaceFn1");
}
}
}
If you then put the cursor on one of the functions in AA and select the "
"pull up" refactor. (Alt+Shift+T, U) - you get the following dialog.
Then click select all on the right, and next.
You get warnings about duplicate functions, which will cause compile errors, in a dialog that looks like this. You can just ignore these, and fix them later.
Then going to finish you get code that looks like this:
public class Temp {
public static interface I1 {
public void interfaceFn1();
public void interfaceFn2();
}
public static abstract class A implements I1 {
int a;
int aa;
public void foo(){
System.out.printf("%s In A a=%d\n", this, a);
}
#Override public void interfaceFn1() {
System.out.println("In A.interfaceFn1");
}
#Override public void foo() {
super.foo();
System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa);
}
#Override public void interfaceFn2() {
System.out.println("In A.interfaceFn1");
}
}
public static class AA extends A {
}
}
You can now remove the class AA and fix the errors in A (duplication of foo() being the main issue) . Resulting in code like this:
public class Temp {
public static interface I1 {
public void interfaceFn1();
public void interfaceFn2();
}
public static abstract class A implements I1 {
int a;
int aa;
private void fooBase(){
System.out.printf("%s In A.fooBase a=%d\n", this, a);
}
#Override public void interfaceFn1() {
System.out.println("In A.interfaceFn1");
}
public void foo() {
fooBase();
System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa);
}
#Override public void interfaceFn2() {
System.out.println("In A.interfaceFn1");
}
}
}
The biggest remaining problem is to switch all creations/references of AA to A. But if you selected the use destination type where possible that will reduce the number of places you will need to fix.
I suspect there are still cases where constructors cause some issues, but this seems OK for most cases.
It is really hard (if not impossible) to automate the combination of two hierarchy classes: consider the following: you have two classes
public static class A {
int a;
public void foo(){
//do stuff
}
}
public static class AA extends A {
int aa;
#Override
public void foo(){
//do stuff
}
}
When you merge them, you run into the problem:
public static class AMerged{
int a;
int aa; //this is fine
public void foo(){ //but use who's implementation?
//do what?
}
}
With this, you run into the problem of method names being the same name, same with variables being the same, who's implementation will I use? The child or parent? As you can see, there are lots of problems in merging two classes you will run into, so it is nearly impossible to automate.
Even with abstract classes there is no way to combine them other than to do it manually
Actually, this can be done by class inline.
First, you need to pull up subclass method to parent class;
Then, you can inline the subclass. (Intellij Idea, place cursor on subclass, refactor->inline. Intellij Idea will remove subclass, and replace subclass with parent class)
I have a class (let's say Vehicle) with a rather large number of subclasses (Car, Bike, ..). Every subclass stores specific information on the type of the subclass (# of tires, ..).
I want to ensure that all this information is already enforced (at compile-time).
So I don't want to specify this data in the constructor of the subclass (because I might forget to set some of them). I could put this info in the constructor of Vehicle, but this would clutter code quite a lot, since I have many of those parameters.
public class Vehicle {
int numberOfTires;
public Vehicle(int numberOfTires, ...) {
...
}
}
public class Bike {
public Bike() {
super(2,...);
...
}
}
I end up with completely unreadable constructors. It would also store this info per instance, even though it is specific to the subclass.
An alternative way is to introduce abstract static getters/setters and store the info in the subclasses.
public class Vehicle {
...
abstract public int getNumberOfTires();
}
public class Bike {
static int numberofTires = 2;
...
public int getNumberOfTires() {
return numberOfTires;
}
}
This seems way cleaner and also stores the info per subclass and not per instance but there will be a lot of code duplication in the subclasses. Right now, all the subclasses contain ~20 setters/getters but virtually no real functionality. Is there a clean way of avoiding this? Perhaps using the Factory method or alike?
In your shoes, I'd do it this way
public abstract class Vehicle {
public abstract int getNumberOfTires();
}
and
public class Bike extends Vehicle {
#Override
public int getNumberOfTires() {
return 2;
}
}
and
public class Car extends Vehicle {
#Override
public int getNumberOfTires() {
return 4;
}
}
You should put in your Vehicule class everything that is common. If the number of tires is a common attribute of all your Vehicule, than it belongs there.
Using the factory pattern you could avoid having to write each time you want a instance of a Bike all that is needed in the Vehicule class as the factory would do that. Meaning the code that sets the parameters of a Bike is written in one place, the BikeFactory class.
That would make the line creating a Bike looks like
Bike yourBike = BikeFactory.getInstance().create();
instead of
Bike yourBike = new Bike(numberOfTires, ... );
The factory would have either a line that looks like the above one or a bunch of calls to setters. I would recommend you use setters and just a new Bike() constructor without parameter.
The naming of the factory, methods and the factory being a singleton are only as example and can be implemented as you see fit in your application.
As mentionned, you could also use another class for the parameters but that only move the hassle of settings your parameters somewhere else.
Seems to me that what you are talking about here are constants, e.g. values that are not supposed to change at runtime. In Java, constants are variables with the following qualifiers: static final, along with private/public. Then, you won't need setters, since a Bike will never anything other than 2 wheels for instance.
I don't really see the problem with having lots of getters and setters, your Bike-class has a set of properties describing it, and they are all needed. So something like:
public abstract class Vehicle {
public abstract int numberOfTires();
public abstract boolean hasEngine();
}
public class Bike extends Vehicle {
private static final int NUMBER_OF_TIRES = 2;
private static final boolean HAS_ENGINE = false;
public int numberOfTires() {
return NUMBER_OF_TIRES;
}
public boolean hasEngine() {
return HAS_ENGINE;
}
}
These variables are properties of the entity that you are representing, and as per object-oriented principles, they belong as members of the class.
All domain classes will have a number of variables, and in most cases they will require at least a getter, there is no way around this. Still, it is good to keep your domain classes as small as possible, not necessarily with regards to lines of code, concepts it represents. If a domain class has grown large, decompose it and group variables that belong together is separate classes. Then each of the smaller classes will have a constructor with a limited amount of variables, and instance creation
If all that matters in limiting the amount of code in your subclasses you could do something like the code below. I'm not sure if I would recommend it though, and I don't think I'd do this in practice.
public abstract class VehicleInfo {
public abstract int numberOfWheels();
}
public class BikeInfo extends VehicleInfo {
#Override
public int numberOfWheels() {
return 2;
}
}
public class CarInfo extends VehicleInfo {
#Override
public int numberOfWheels() {
return 4;
}
}
public class Vehicle {
final VehicleInfo info;
Vehicle(final VehicleInfo info) {
this.info = info;
}
public int numberOfWheels() {
return info.numberOfWheels();
}
}
public class Bike extends Vehicle {
public Bike() {
super(new BikeInfo());
}
}
public class Car extends Vehicle {
public Car() {
super(new CarInfo());
}
}
This way all getters are located in the superclass (as well as in the info-classes), and the subclasses can stay clean.
I am attempting to create a generic/parameterized code to call from multiple classes I have. I will code it so I have several classes that have methods of the same name, so I'm hoping to create a generic way to call them.
Say I have 3 different classes that will all have methods that are called getAmount() that return ints and toString() methods that return Strings
Then I want a generic class that could possibly reference any of those three.
public class Stuff<Project> {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
public String toString() {
return p.toString();
}
Is there anything in java that would get this functionality for me, or am i thinking in C?
I've tried using Object.getClass() in various ways to attempt to cast things, and several of the other Generic programming related questions on this site and the docs.oracle site don't seem to have what I'm looking for. Is this not possible because of the way type erasure works?
Don't use generics here, use interfaces. In Java, you use interfaces to tell the compiler that a class implements certain methods, without telling it how these methods are implemented.
public interface Project {
int getAmount();
}
public class Stuff {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
}
You can pass an instance of any class to Stuff's constructor, as long as it implements the Project interface:
public class Construction implements Project {
public int getAmount() {
// implementation
}
}
...
Stuff s = new Stuff(new Construction());
You can use an interface, an abstract class or reflection. I would avoid using reflection unless you really need it. This looks like the perfect job for an interface.
public interface Ammount {
public int getAmmount();
}
public class BankAccount implements Ammount {
#Override
public int getAmmount() {
return -10; // broke
}
}
public class PiggyBank implements Ammount {
#Override
public int getAmmount() {
return 12; // rich
}
}
You can then use some code like
BankAccount myBankAccount = new BankAccount();
Ammount ammount = myBankAccount;
ammount.getAmmount();
PiggyBank myPiggyBank = new PiggyBank();
Ammount ammount = myPiggyBank;
ammount.getAmmount();
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
System.out.println("Dont go here please");
}
public void thisMethod(SpecificFoo specificFoo) {
// not into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}
calling code:
SomeClass myClass = new SomeClass();
SomeOlderClass olderClass = new SomeOlderClass(myClass);
I have an interface (SomeInterface) that several classes call into (such as SomeOlderClass). I have a class that implements the interface, but I want to do type safe operations on the specific implementations that are passed into the generic interface.
As shown in the above code, I really want to able to make another method that matches the specific type passed in to the interface. This doesn't work. I assume it is because the calling code only knows about the interface, and not the implementation with the more specific methods (even though SpecificFoo implements Foo)
So how can I do this in the most elegant way? I can get the code working by adding an if statement in the class implementing the interface (SomeClass):
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
if ( someKindOfFoo.getClass().equals(SpecificFoo.class) )
thisMethod(SpecificFoo.class.cast(someKindOfFoo));
else
System.out.println("Dont go here please");
}
However, this is not elegant, as I have to add if statements everytime I add a new kind of Foo. And I might forget to do so.
The other option is to add SpecificFoo to the SomeInterface, and let the compiler sort out reminding me that I need implementations in SomeClass. The problem with this is that I end up adding quite a bit of boiler plate code. (If someone else implements the interface, they have to implement the new method, as well as any tests)
It seems that there should be another option I am missing, given that Foo and SpecificFoo are related. Ideas?
MORE INFO:
Well I actually worked for a while to try and simplify the question. As I add more details the complexity goes up by quite a bit. But whatever... I think I can explain it.
Basically, I am write a GWT web apps RPC servlet using the command pattern as explained by Ray Ryan in his talk
There are several implementations of it on google code, but many of them suffer this inherit problem. I thought it was a bug in the GWT-RPC code bugreport HOWEVER, as I was implementing further I noticed a similar problem happening purely on the client side, and while in hosted mode. (ie all java, no gwt javascript madness).
So I abstracted the basic ideas to a raw java command line case, and saw the same issue, as described above.
If you follow along with what Ray Ryan discusses, Foo is an Action, SpecificFoo is a specific action I want to call. SomeInterface is the client side RPC service and SomeClass is the server side RPC class. SomeOlderClass is a kind of rpc service that would know about cacheing and whatnot.
Obvious, right? Well as I said, I think all the GWT RPC nonsense just muddies up the waters on the base issue, which is why I tried to simplify it as best I could.
If you need to find out the actual type of an object at runtime, then the design is most probably wrong. That violates at least the Open Closed Principle and Dependency Inversion Principle.
(Because Java does not have multiple dispatch, the thisMethod(Foo)will be called instead of thisMethod(SpecificFoo). Double dispatch could be used to get around the language's limitations, but there might still be some design problem lurking there...)
Please give more information on what you are trying to accomplish. Right now the question does not provide enough information to come up with a right design.
A generic solution is that since the action depends on the runtime type of Foo, that method should be part of Foo so that its implementation can vary depending on Foo's type. So your example would be changed to something like below (possibly adding SomeInterface or other parameters to thisMethod()).
public interface Foo {
void thisMethod();
}
public class SpecificFoo implements Foo {
public void thisMethod() {
System.out.println("Go here please");
}
}
Try using double dispatch: Add a method to the Foo interface that is called by SomeClass#thisMethod. Then place the code in the implementation of this method.
public interface Foo {
public void thatMethod(SomeClass a);
public void thatMethod(SomeOlderClass a);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
someKindOfFoo.thatMethod(this);
}
}
Sorry, I find the problem description far too abstract to be able to make a recommendation. You clearly have a design issue because you generally should not need to check the type of interface. I will give it a go though... First, I need to make your problem more concrete for my small brain to understand. Instead of Foos, how about Birds?
public interface Bird {
}
public class Ostrich implements Bird {
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
System.out.println("I am in the air. Yay!");
}
public void fly(Ostrich ostrich) {
System.out.println("Sigh... I can't fly.");
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Here, the Ostrich will declare "I am in the air. Yay!" which is not what we want.
OK, so, ignoring the fact that I am failing basic OO here, the problem is that the BirdManager will look for the least-specific method that matches the type that is passed in. So no matter what kind of bird I give it, it will always match fly(Bird). We can put some if checks in there, but as you add more types of birds, your design will degrade further. Here's the tough part - I have no idea if this makes sense within the context of your problem, but consider this refactoring where I move the logic from the manager into bird:
public interface Bird {
void fly();
}
public class BasicBird implements Bird {
public void fly() {
System.out.println("I am in the air. Yay!");
}
}
public class Ostrich implements Bird {
public void fly() {
System.out.println("Sigh... I can't fly.");
}
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
bird.fly();
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Our Ostrich now says the correct thing and the bird manager still treats it as just a bird. Again, bad OO (Ostriches should not have fly() methods) but it illustrates my thoughts.
As long as there are not too many implementations of Foo, I would declare an abstract method in SomeInterface for each subclass of Foo, and have an abstract class forward calls to a default method that is defined for the most general type:
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
void thisMethod(SpecificFoo specificFoo);
void thisMethod(OtherSpecificFoo otherSpecificFoo);
}
public abstract class AbstractSomeInterface {
public void thisMethod(Foo wrongFoo) {
throw new IllegalArgumentException("Wrong kind of Foo!");
}
public void thisMethod(SpecificFoo specificFoo) {
this.thisMethod((Foo) specificFoo);
}
public void thisMethod(OtherSpecificFoo otherSpecificFoo) {
this.thisMethod((Foo) specificFoo);
}
}
public class SomeClass extends AbstractSomeInterface {
public void thisMethod(SpecificFoo specificFoo) {
// calling code goes into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}