Im trying to implement an interface that should affect some objects of a class but not others.
For example lets say this is my code:
public interface KnowsHowToSwim{
double getHowFast();
}
public class Stable{
Horse pinky = new Horse(veryFast);
Horse lightning = new Horse(veryPretty){
#Override
public float getPrettynessFactor(){
return super.getPrettynessFactor()*10000000000
}
};
Horse wetty = new Horse(soCool); <-- This one should KnowHowToSwim
}
Now, i know I can create a new class that extends horse and implements KnowHowToSwim, but since my application will have a lot of fields from different classes that will implement that interface, I was wondering if there was a way to implement the interface in a specific object similar to how Horse lightning overrides its method.
No you can't.
You wan't something like a trait or mixin, which is not supported in Java.
Java8's default methods in interfaces won't work for you because you need a property in the instance (or access to the instance), which is not possible. Default methods have no reference to this.
Further, from a OO perspective, you have to define a separate class, extending Horse and implementing KnowsHowToSwim. All instances of this are a Horse and know-how-swim. Of course you can create only one instance of it.
However you may define a class inside a method body (i.e. a factory method), a.k.a. local class. This class hold referece to all (effectively final) variables in the method. For example:
public static Horse newSwimmingHorse() {
final Object methodScopeProperty = ...;
class SwimmingHorse extends Horse implements KnowsHowToSwim {
double speed;
double getHowFast(){
methodScopeProperty.doSomething(); //do you need this access?
return speed;
}
}
return new SwimmingHorse();
}
But as long as you don't gain any benefits from the accessible method scope I wouldn't recommend it. Use a static inner class instead, optionally with limited visibility or a package-private class. This keeps your code more cohesive.
Related
I have an abstract class called Car. Then I have two subclasses, Ford and Dodge which both extend Car. Each of these subclasses have a method called move(). The code in this method is identical for Ford and Dodge, so naturally my instinct was to throw this method implementation into the Car superclass so I don't have to have the same code twice in both my subclasses, i.e. get duplicated code, and just have this method written out once in code inside the superclass, and each subclass can call it when it needs to.
Now here's my...thing: Inside the move methods in each subclass, instance variables from each subclass are being manipulated. So you see, even though the code is identical, what is happening in each move()-method is depending on the state of that specific subclass's instance variables. Like this:
abstract class Car {
// I want to put move()-method in here and erase it from subclasses
}
class Ford extends Car {
private int rpm;
public void move(){
dosomestuff + rpm // value of rpm being used here is unique to Ford
}
}
class Dodge extends Car {
private int rpm;
public void move(){
dosomestuff + rpm // value of rpm being used here is unique to Dodge
}
}
I want to have it like this, and call move() in the superclass from each subclass using the subclasses instance variables:
abstract class Car {
move(){
// do stuff that is identical to Ford and Dodge but
// dependent on different instance variables
}
}
class Ford extends Car {
private int rpm;
}
class Dodge extends Car {
private int rpm;
}
Should I create variables inside the superclass Car? But that is what I am having problem wrapping my head around, because I know an abstract class cannot be instantiated! So if I were to pass the rpm-variable in this case as a parameter in the move() method like move(rpm), while I am having the implementation for move() only inside the Car class, I would have to return the rpm-variable to get its manipulated value back. This works, for once instance variable form a subclass. The problem is, the move-methods depend on several different kinds of variables. So I would have to return several variables back to the subclass each time but I am not sure how to do that.
I am confused. How can I condense this "duplicated code" inside my subclasses into the superclass Car and still be able to manipulate instance variables from the different subclasses inheriting from the Car class? Do I pass them as parameters and return them? Do I do something with get-set methods? I am so unsure...
Use protected variables
abstract class Car {
protected int rpm;
move(){
// ACCESS RPM HERE, which would be specific to implementing class
}
}
class Ford extends Car {
}
class Dodge extends Car {
}
Since the variable rpm is now protected, it will be accessible to the sub-classes of Car and when you instantiate Ford or Dodge, it would have it's own rpm value.
Makes sense?
I do not know if this answers your questions but sub classes inherit the methods of super classes so I would put everything in the abstract class and use getter setter (or access-mutate) methods to use all the variables in the abstract class. I notice someone has stated protected variables which will work sometimes but not if you need encapsulation within your package. I would do this:
public abstract class Car{
private int rpm;
public int getRPM(){return rpm;}
public void move(){//do move using getRPM() to access the data}
}
class Ford extends Car {
}
class Dodge extends Car {
}
So then the only thing different between Ford and Doge will be the constructor which is often times good when you are subclassing
As others have written, you can pull your instance variables into your base class; and make them either protected; or provide getters for them; but honestly, I think that most likely will lead to a bad design.
The thing is: inheritance should be used to provide behavior to its subclasses, not variables.
Meaning: you consider carefully what kind of behavior you want to "share"; and then you think about the open closed principle to implement it the right way, like:
abstract class Base {
public final void doTheCommonThing() {
System.out.println("but we need subclass stuff: " + getFromSubclass());
}
protected abstract String getFromSubclass();
}
The whole point of data encapsulation is that your base class should not know about variables in child classes; and vice versa. Because those are implementation details that nobody else has a business knowing about.
There is an abstract class containing non-abstract methods only. Now I create another class which extends abstract class. For ex :
abstract class Parent{
void No(){
System.out.println("abcd");
}
}
class Child extends Parent {
}
Instead of abstract class, I could have create another class. What is use of making this above class as an Abstract ?
I guess what you want to know is if in this case it make any difference not to make abstract:
No it doesn't: as long as you do not have abstract methods, you can use abstract or non-abstract classes (even if abstract makes no sense in this case). But if you've one abstract method, you class needs to be marked as abstract.
an abstract class without any abstract methods sometimes is a design decision. for example, a regular expression can be implemented like this:
public abstract class Regex {
private Regex(String pattern) { /* do something */ }
private static class ConcreteRegex {
private ConcreteRegex(String pattern) {
super(pattern);
}
}
private static final int MAX_CACHE_SIZE = 100;
private static Object cacheLock = new Object();
private static Queue<String> patternq = new LinkedList<>();
private static Map<String, Regex> cache = new HashMap<>();
private static Regex checkCache(String pattern) {
synchronized(cacheLock) {
return cache.get(pattern);
}
}
private static void insertCache(String pattern, Regex regex) {
synchronized(cacheLock) {
patternq.offer(pattern);
cache.put(pattern, regex);
while(patternq.size() >= MAX_CACHE_SIZE) {
String key = patternq.poll();
cache.remove(key);
}
}
}
public static Regex compile(String pattern) {
Regex result = checkCache(pattern);
if (result == null) {
Regex compiled = new ConcreteRegex(pattern);
insertCache(pattern, compiled);
return compiled;
}
return result;
}
public static Matcher match(String pattern, String str) {
Regex result = compile(pattern);
return result.matches(str);
}
// define find, findall, and so on like this
}
so what's the point to do all these work? well, sometimes it would be quite handy to have these methods to shorten the program, while it may have a chance to increase the performance of the program. by doing this, we need to prevent user to call the constructor directly. but why not have these caching management inside of the constructor?
well, this is not recommended(it will compile though), since you are leaking the instance out in the middle of instantiation, such that there is a chance to reference the partially instantiated object, which may generally be considered as a dangerous behavior.
of course, there are other cases where you decide to have such "weird" abstract classes, which are too many to enumerate.
It's true that if an abstract class has no abstract methods, then there's nothing that forcibly prevents would-be clients from creating a trivial child class and instantiating it; but keep in mind that we write code to be read and understood, not just by the compiler, but by other programmers (including our future selves). We cannot forcibly prevent those programmers from messing up; but we can write code that helps them do the right thing.
So the question is — what is a situation where a class has no abstract methods, but where it nonetheless doesn't make sense to instantiate it directly?
There are a few possibilities that come to mind, but I'll just mention one.
Consider an interface like java.util.List, where many of the methods are convenience methods that can be defined in terms of others. In particular, the methods that use iterators can be defined in terms of the methods that use indices, and vice versa.
One could easily imagine an abstract List implementation that defines all of these methods, but in terms of each other. You could then easily implement List by subclassing this implementation and overriding either an iterator-y method or an index-y method.
(As it happens, this is not the approach the JDK takes. The JDK instead offers two abstract implementations, java.util.AbstractList and java.util.AbstractSequentialList, each of which has some abstract methods for the subclass to fill in. I think the JDK's approach is superior, because it makes it clearer what you are supposed to do, and generates a compile-error where the combined-abstract-class approach generates a StackOverflowError at runtime. But I would not fault the developer who, with a surfeit of DRY, took the combined-abstract-class approach.)
One advantage I see is that you prevent people instantiate it.
For example you want to make a system of vehicle. In the parent abstract class, there is only one method run(){}, well, not abstract. You want to instantiate it as VW, TOYOTA OR Ford, but not a non-specified brand vehicle. You inherent vehicle class as non abstract class VW, Toyota or Ford. but you couldn't start with vehicle, cuz it's more like a "type", not something you want to build.
I have a problem with my abstract class.
Here is my interface:
package dovilesUzduotis4;
import java.util.ArrayList;
public interface Interface1 {
void a(ArrayList<K> kM, String g);
}
and abstract class:
package dovilesUzduotis4;
import java.util.ArrayList;
public abstract class Service implements Interface1 {
public void iK(ArrayList<Ks> kM, String g){
K aK = new K(g);
kM.add(aK);
}
}
But when I try to use service.iK(kM,g); in main I get the error "service cannot be resolved". How can I correct that?
Please paste in the main method first.
My guess is you forgot to instantiate an object of the class:
Service service= new Service() { //create an object of the class
}; //brackets are there because the Service is abstract class and I am redefining it.
service.iK(kM, g); //invoke a method an that object
Now, I don't think that the Service class needs to be abstract. You render the class abstract if you expect a user to implement a method (or methods) of that class that is marked as abstract in a manner that suits his needs. Needless to say, I don't see any abstract method in your Service class.
So it comes to this:
if the class is NOT abstract, you instantiate it as:
Service service= new Service();
if the class is abstract, you must redefine it at place:
Service service= new Service() {
//here you could implement an abstract method or redefine an existing one
};
First of all, Java is case-sensitive meaning that service and Service are different things. The error you just got: service cannot be resolved says, that service class is expected, while you have Service class.
Remember, that class names should implement the CamelCase, while variable names should start with a small letter.
To call methods you must either:
Create an object and access its method
Or make the method static
In the first case, you have to implement a child class:
SubService extends Service {}
because service is abstract and is expected to be extended.
Then:
SubService service = new SubService();
service.method();
In the second case, you do not have to extend the class, static methods can be called.
public abstract class Service implements Interface1 {
public static void iK(ArrayList<Ks> kM, String g){ //static method
K aK = new K(g);
kM.add(aK);
}
}
Then:
Service.iK(arg0, arg1);
This topic is suitable only for deletion.
ArrayList operates on Ks type, and you guys are putting inside it an K type object...
You should extend this class, or make it not abstract (by implementing interface) if you want to instantiate it.
Your specific example seems to be related to some sort of webservice api. Without the backing code to the abstract class we can't really help you there.
I think we can start with some simple fundamentals related to interfaces and abstract classes, since that seems to be your question.
Abstract classes are classes that you cannot, by definition, create an instance of. What darijan did to "construct" and instance of the abstract class is he is creating an anonymous inner class for the Service abstract type.
Service service= new Service() { }; // notice the curly braces, this is an anonymous class definition
There are many different schools of thought and opinions related to best practices with abstract classes and interfaces. What we really are talking about here is the heart of OOP, in my opinion. Abstract classes are meant to provide APIs with or without concrete implementation, so that they may be overridden and specialized for a specific purpose.
This would be a decent example:
public class Car {
String make;
public car (String make) { this.make = make; }
}
public class Hondacar extends Car{
public Hondacar() { super("honda"); }
}
Now you have the definition of what states define a "Car" object, and then you specialize that into the definition of a "Hondacar".
Hopefully this makes sense.
Onto interfaces... Interfaces are declarations of a public API. They are a "contract" that implementing classes must abide by. A class that implements an interface must, by definition, implement all methods on that interface. YOU CAN THINK of an interface as an abstract class with only abstract methods, where classes that subclass that abstract class will need to override every method on that supertype(this draws parallels to the "#override" annotation on implemented interface methods) though many will probably discourage this way of thought. I am not sure what you are trying to do with your specific example since it does not have any names that I can even draw inference from so I can't really help you there.
So drawing on the whole car example, a similar design would be:
interface Car {
String getMake();
}
class HondaCar implements Car {
private static final make = "honda";
#override
public String getMake() { return HondaCar.make; }
}
You can see how the interface does not provide any sort of implementation at all, it merely defines the public API that an implementing class must offer.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class? Therefore having object A which uses the interface and object B which does not use it.
Thanks
Updated:
Assuming you have a Professor class and this class implements an interface called Employer, which has employ(rAssist x) abstract method.
Now I want to instantiated 2 objects from the Professor class implementing this interface Object A - Professor can employ a research assistant and Object B - Professor cannot employ research assistants.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class?
No, if class C implements the interface, then all instances of C will provide the methods declared in the interface.
What you can do is something like
class MyClass implements MyInterface {
#Override
void interfaceMethod() {
System.out.println("Interface method");
}
}
and then do
MyClass x = new MyClass();
MyClass y = new MyClass() {
#Override
void interfaceMethod() {
throw new UnsupportedOperationException();
}
};
In effect, x supports the use of interfaceMethod while y does not. Note however that...
The usage of y.interfaceMethod is not prevented at compile-time, i.e. it will not be enforced by the type system.
With this solution, you are in fact creating an (anonymous) subclass of MyClass and assigning an instance of it to y.
Do you mean you want class A and Class B to implement a common Interface but you dont want to implement all methods in Class B?
An Interface in simple terms means it is sort of a contract and all the classes which implement it should follow that contract.So if you want Class B to implement the interface , Class B should also follow the same contract. But if you dont want to implement any methos you can always do this.
class ISampleInterface {
void sampleMethod();
void optionalMethod();
}
Class A implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
//Your Implementation
}
}
class B implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
throw new UnsupportedMethodException();
}
}
No, that's not the point of an Interface.
An Interface is contract that guarantees that implementations WILL implement it's signature
The idea of interface is to establish a obligation for the class that implements the interface.
If your's is a requirement, you can use the java.lang.reflect.Method reflection class to change the visibility of the method at runtime. However, this is not a clean way.
1. Interfaces were introduced in Java because Multiple Inheritance was not allowed in Java.
2. But as far as Design Pattern are concerned, following are the uses..
- To implement certain Roles.
Consider Dog a Super class, but then Pet dog and Wild dog can be interfaces, which
can be implemented by the Sub Classes of Dog class.
- Used when Behaviors keeps changing.
Consider you have a Class Drawing, and paint method() in it, now paint can be stroking, shading, etc...
You must Encapsulate such behaviors in an Interface or an Abstract class.
if we have 2 class Zoo & Moo as follows:
public class zoo {
String superString="super";
private String coolMethod(){
return "Zoo method";
}
}
public class Moo extends zoo{
public void useMyCoolMethod(){
zoo z=new zoo();
System.out.println(superString);//1
System.out.println(z.superString);//2
}
public static void main(String[]args){
new Moo().useMyCoolMethod();
}
}
at 1 & 2 we print the value of the String in the super class through inheritance and access, the question is , what is the benefit of Access although i can do the same thing by inheritance ? knowing that the Access approach isn't allowed if the two classes is in diff packages
By accessing through the object ref you are modifying the referenced object's state, by inheritance you are modifying the object you are currently in ( this reference ). So there is actually no benefit aside from encapsulation at class level and package level through out the access modifiers and that sort of thing, you just use it depending on the behavior you want for you're code, or in this case, how restrictive to modify the state of objects depending on the context.
But aside from that, i'm not sure if there is anything else.
Regarding your example there is no benefit at all in "access" the method, if you really wants to print "super" twice.
But normally OO programs contains more than two classes and the authors tries to modularize the code with defined interfaces (aka public methods or an API). Create modules with inheritance only is very hard and create clumsy code. So objects will need other instances and call there method by "access".
In line 1, you are using inheritance, i.e. you have a class animal and you have method move() which moves the animal using his four leg. But in case of Kangaroo, you want to use most of the feature of animal class but want to change how it moves based on the fact that it jumps and uses it hind leg for movement.
In Line 2, you are using composition, i.e. when you want to create car, you will need different component and they will interact with each other for that car to function. Here you can not inherit from GearBox or Engine but you have to use them as part of Car (or what you are calling access).
In the end its the relationship between Zoo and Moo will decide what method you want to use
Using this access and inheritance is same when you do Not want to modify the content of the inherited memeber..
eg:
public class A {
String s = "Hello";
}
public class B extends A{
String s = "Hi;
System.out.println(s); // Will print the s in class B
System.out.println(new A().s); // Will print the s in class A
}
Now as String s has no modifier, it is considered having Default modifier, that means it can be accessed by classes only with in its own package.
If you use protected access modifier, then you Need to extend the class and then use the inherited members, but you can Not use the protected member by creating an instance of the class that holds it and then use dot operator to access it, this will Not work..
eg :
package com.go;
public class A {
protected String s= "Hi";
}
package com.fo;
public class B extends A {
System.out.println(s); // This will work
A a = new A();
System.out.println(a.s); // This will NOT work
}
The access (default or package-private) would be useful if Moo was in the same package an didn't extend Zoo.
First of all, I think is a good practice to maintain class attributes with private visibility, and access them through getters and setters. In second place, you are not accessing the attribute by inheritance, you are creating an instance of Zoo, and accessing the superString attribute because of it package visibility, you could also access them from another class of the package that don't even extends Zoo class (and that's generally not a good thing) In third place, you don't need to create an instance of the super class to access his public or default attribute, you could simply do:
System.out.println(this.superString)
wich is absolutly the same as (if not local variable or parameter declared with the same name):
System.out.println(superString)
In conclusion, having default or public attributes, let client classes access them (read and write) without the class could do nothing about it, and this could bring side effects for the methods of the class that use those attributes.
Example 2 you have a separate instance of your zoo object, which is a bit weird, but since the method will always return the same thing there isn't much difference. If you changed your method to be based on constructor input or something you could see a difference in the 2.
public class zoo {
public String superString;
public zoo (String _superstring) {
superString = _superstring;
}
}
public class Moo extends zoo{
public void useMyCoolMethod(){
zoo z=new zoo("string1");
System.out.println(superString);//1
System.out.println(z.superString);//2
}
public Moo (String _superstring) {
superString = _superstring;
}
public static void main(String[]args){
new Moo("string2").useMyCoolMethod();
}
}
Will return
string2
string1