I have two classes that extends a third class, i.e.
public class class_a extends parent_class
and
public class class_b extends parent_class
My question is it possible to have a third class to create a reference to a class based on condition? i.e.
public void test() {
parent_class b;
if (cond)
b = new class_a();
else
b = new class_b();
}
Is there a way to do that?
I don't want to create variables per type of class, I will only use one throughout the life time of this function.
That is exactly what the factory design pattern is for.
http://en.wikipedia.org/wiki/Factory_method_pattern
This might also be of use Factory Pattern. When to use factory methods?
Yes.
Polymorphism allows you threat subclass as base class.
So, you can write method with parent_class return value type, like so:
parent_class create(boolean condition)
{
return condition ? new class_a() : new class_b();
}
As #John answered, it is called Factory method.
P.S. In Java, you better should name classes using CamelCase, like ClassA and ParentClass. Code style.
Related
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.
I am searching for a solution to my problem for a while now but I cannot find an answer which is specific for my question.
I have a Class A which is abstract and Class B and C which extends class A. A and B are concrete classes. Class A implements function which will be inherited by V and C. Inside this function I want to create new object of B or C - the problem is that I don't know which object is that.
How can I achieve this?
public void colision(List<Organism> organisms) {
List<Organism> temp = new ArrayList<Organism>(organisms);
temp.remove(this);
for (Organizm organism : temp){
if (this.location == organizm.getLocation()){
if (this.getClass().equals(organism.getClass())){
//here is what I need to figure out
}
else{
...
}
}
}
}
}
Use Class<T>.newInstance() e.g.:
organism.getClass().newInstance().
In order to do that you need to have default constructor in your class definition otherwise you need to find constructor - e.g.:
Constructor constructor = organism.getClass().getDeclaredConstructor(parameterTypes...); and then use it like constructor.newInstance(arguments...);.
Use the Factory design pattern
Probably you can have an abstract method getInstance() in A and then have both B and C implement that method
So if I instantiate a class in another class in Java, isn't that inheritance, because I am calling its method?
For example,
public void updateStock(int stockNew){
stockFinal = stockNew;
Stock stock = new Stock();
stock.update(stockFinal);
}
Isn't that inheritance, because I am able to call the method, update().
This is inheritance:
public class Base
{
public String Hello() {
return "hello";
}
public class SubClass extends Base
{
}
Then it's used like this:
SubClass sc = new SubClass();
sc.Hello(); // returns "hello"
or
Base b = new SubClass();
b.Hello(); // calls the same as above
Or this, calling the base from an overridden method:
public class SubClass extends Base
{
//#Override
public String Hello(){
return super.Hello() + " + override!!!";
}
}
The keyword super refers to the classes ancestor.
No this is not inheritance. You are just calling the class itself.
No, that's not inheritance. Inheritance is when a class extends another class. Inheritance is about establishing an is-a relationship, like a Car is a Vehicle. Or a List is a Collection.
In your example, you're just creating a new object or another type and calling a method on it. If you, of type Human, are using a car, of type Car, that doesn't make a Car a Human.
No, that isn't inheritance. Inheritance is when a class extends or implements another class. For more information go here
Here
You can find an explanation of what is OOP and its principles!
This is not inheritance.
You are just creating a object of a class.
You can use method and data member of other class but object of base class can't use method or data member of your class.
No, using a class is not the same as inheriting the characteristics of a class.
See the official Java Tutorial to learn more.
I know this is probably pretty basic, and I'm ashamed for not knowing how to do this (and worse yet, being unsuccessful in searching for a solution).
How would I pass an object of type thing from A to C?
public class A extends B {
}
public class B {
public class thing {
}
}
public class C extends JFrame {
}
I have access to thing in A because I'm extending B, but I'm unable to extend B when using class C because I need to extend JFrame.
EDIT
Sorry for the vagueness. Class A has a collection of objects of type thing and I want to iterate through those objects in class C.
EDIT 2
And of course... the obvious choice. Make thing its own class... :(
Admitting shame for the sake of those who may also have an issue like this.
First, if it's an inner class - you probably shouldn't access it from the outside...
But, if you insist, you can try to do as follows:
public class A extends B {
}
public class B {
public class thing {
}
private thing mything = new thing();
public thing getThing(){
return mything;
}
}
public class C extends JFrame {
A a = new A();
Object thing = a.getThing();
}
accessing an inner class from the outside is generally a bad idea, but if you must i wold suggest looking at the delegate design pattern like in this article :
delegate design pattern
You probably trying to use multi-inheritance which is not possible in java!
you can use interfaces to have 2 different behavior or Use some design patterns
to achieve such a goal.
It's really unclear what you are trying to do.however see composite or factory-method patterns
i think it could help.
I am trying to write a set of User Interfaces that operate similarly for multiple classes, which all extend an abstract class Category: HouseCategory extends Category, CarCategory extends Category
Most of the code works fine just by using polymorphism, but there is one section where I need to create a new instance of the extended category
Obj foo = new HouseCategory(a, b, c)
How can I make this work for all subclasses of Category? - they all have the same constructor arguments. I don't know much about generics, but is it possible for me to have the UI class defined as
public class UserInterface <T extends Category> extends JFrame {
or possibly
public class UserInterface extends JFrame {
public UserInterface(Class<T extends Category> clazz) {
and build from there?
Help much appreciated.
EDIT: Also, is it possible to get a static field from the generic class?
I'd rather not have to have a statement checking "if (clazz instanceof HouseCategory) name = HouseCategory.NAME" as there may be hundreds of classes.
Introduce a new factory to create the category objects or the user interfaces. The factory needs to be extended whenever you add a new category, but that shouldn't be a big problem:
public class CategoryFactory {
public static enum Type {HOUSE, CAR}
public static Category createCategory(Type type, Param a, Param 2, Param b) {
if (type == null) return null;
switch(Type) {
case HOUSE: return new HouseCategory(a,b,c);
case CAR: return new CarCategory(a,b,c);
}
return null; // or throw exception -> tells, that a new enum is not handled yet
}
}
Then, if you protect the constructors in the category subclasses and keep those subclasses and the factory in one package, you can make it pretty difficult to bypass the factory.
Generics can't really help you with this due to type erasure. At runtime your code doesn't "know" the values of the type parameters.
One approach would be to use the factory pattern. Create a factory class for each Category and have these all implement a common factory interface (probably CategoryFactory). Then give factory objects to the UserInterface rather than Class objects.
Another approach would be to use reflection to invoke the constructor on the Class object. I'm not a fan of this approach as it throws compile time checking out the window, but it would involve using the getConstructor method on the Class.
Pass the class to the interface. Use reflection to invoke the constructor and access the NAME field. But it's better to employ instance methods that subclass can override:
/** subclass must have the default constructor */
abstract class Category
abstract void init(a, b, c);
abstract String name();
class HouseCategory extends Category
void init(a, b, c){ ... }
String name(){ return "House"; }
class UserInterface
UserInterface(clazz)
Category foo = (Category)clazz.newInstance();
foo.init(a,b,c);
String name = foo.name();