I have an abstract class MotorFahrzeug and an extending class LKW as shown below. I wrote a generic class with type parameter <T extends MotorFahrzeug> implementing a comparator. I'm wondering why the method compare( T m1, T m2 ) in this generic class has access to the protected fields. Can someone explain this, please?
package de.bauer;
public abstract class MotorFahrzeug {
protected int id;
protected int hubraum;
protected int leistung;
// some stuff
}
}
package de.bauer;
public class LKW extends MotorFahrzeug {
private String kategorie = "Nutzfahrzeug";
// Konstruktor
LKW(int i, int l, int h) {
// some stuff
}
// some stuff
}
package de.bauer;
import java.util.Comparator;
public class VergleichHubraum<T extends MotorFahrzeug> implements Comparator<T> {
#Override
public int compare(T m1, T m2) {
int retValue = -1;
if( m1.hubraum == m2.hubraum)
retValue = 0;
if( m1.hubraum > m2.hubraum)
retValue = 1;
return retValue;
}
}
With a declaration like
package de.bauer;
public class VergleichHubraum<T extends MotorFahrzeug> implements Comparator<T> {
The type T is guaranteed to be bound to a subtype of MotorFahrzeug. Since MotorFahrzeug is in the same package as the class declared above, you can access any of its protected members through a reference of type T.
Related
Here are the classes declarations:
public interface IPoint<N extends Number> {
...
}
public abstract class PointP<N extends Number> implements IPoint<N> {
...
}
public class Pointf extends PointP<Float> {
...
}
public interface ISegment<T extends Number, P extends IPoint<T>> {
...
}
public abstract class SegmentP<N extends Number, P extends IPoint<N>> implements ISegment<N, P> {
...
}
public class Segmentf extends SegmentP<Float, Pointf> {
...
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, IPoint<N>>> implements Iterable<S>, Iterator<S> {
...
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
...
}
The compiler refuses the Segmentf type in the generic declaration of the LinesfIterator class with the error message:
Bound mismatch: The type Segmentf is not a valid substitute for the bounded parameter <S extends ISegment<N,IPoint<N>>> of the type LinesPIterator<N,S>
However for me everything seems correct. The declaration of the LinesfIterator class seems to me to have the same hierarchical schema as the Segmentf class which compiles without problem.
Is there a solution to this way of doing things?
As already said, your hierarchy seems to be unnecessarily complex and shall be simplified. For example, I see no meaning in Pointf -> PointP -> IPoint the hierarchy.
If you want to fix your issue, you have to allow a subtype ? extends IPoint<N> in the LinesPIterator class, so:
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>>
implements Iterable<S>, Iterator<S>
{
// ...
}
Moreover, there would be better to implement only Iterable as long as it provides an Iterator and you might end up with duplicated implementation.
public static class LinesfIterator extends LinesPIterator<Segmentf, Pointf, Float> {
#Override
public Iterator<Segmentf> iterator() {
return new Iterator<Segmentf>() {
#Override
public boolean hasNext() { /* TO DO */ }
#Override
public Segmentf next() { /* TO DO */ }
};
}
}
This remark on the use of an anonymous class rather than a direct use really caught my attention because intuitively, when I can avoid going through an anonymous class I do. On the one hand because it is an additional instantiation and on the other hand because it is more difficult to identify at debug (when they are several in the same class).
And I can't see the reasons why I should prefer the use of an anonymous class for this case.
Maybe with my classes as an example the explanation will be easier.
for(Segmentf segment : new LinesfIterator(cube.getPoints(), cube.getIndices())) {
System.out.println(segment);
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> implements Iterable<S>, Iterator<S> {
private N[][] points;
private int[] indices;
private int count;
public LinesPIterator(N[][] points, int[] indices) {
super();
this.points = points;
this.indices = indices;
}
protected abstract S instanciateIteration(final N[] pointDeb, final N[] pointFin);
#Override
public Iterator<S> iterator() {
return this;
}
#Override
public boolean hasNext() {
return count < (indices.length - 1);
}
#Override
public S next() {
return instanciateIteration(points[indices[count++]], points[indices[count++]]);
}
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
public LinesfIterator(Float[][] points, int[] indices) {
super(points, indices);
}
#Override
protected Segmentf instanciateIteration(Float[] point1, Float[] point2) {
return new Segmentf(point1, point2);
}
}
What are the pros/cons of using the abstract class constructor vs. an abstract method for passing final data to an abstract class?
Pass via constructor:
public abstract class MyAbstractClass<T> {
private final String type;
private final Function<String, T> factoryFn;
protected MyAbstractClass(String type, Function<String, T> factoryFn) {
this.type = type;
this.factoryFn = factoryFn;
}
public T doSomething(String value) { ... }
}
Pass via abstract method:
public abstract class MyAbstractClass<T> {
abstract String getType();
abstract T getFactoryFn(String value);
public T doSomething(String value) { ... }
}
I'm aware that the abstract methods can potentially be misused, because it doesn't enforce to always return the same value.
But apart from that, is it just a matter of personal preference, or are there any real (dis)advantages for using one over the other?
I hope I am understanding your question correctly..
Usually, when a property of a class is always held in a field, it is more concise to use an abstract constructor. For example, consider the two following scenarios....
// Scenario 1:
abstract class AClass {
final int field;
public AClass(int f) {
field = f;
}
public int getField() {
return field;
}
}
class Class1 extends AClass {
public Class1(int f) {
super(f);
}
// Class Unique Code...
}
class Class2 extends AClass {
public Class2(int f) {
super(f);
}
// Class Unique Code...
}
// Scenario 2:
abstract class AClass {
public abstract int getField();
}
class Class1 extends AClass {
final int field;
public Class1(int f) {
field = f;
}
#Override
public int getField() {
return field;
}
// Class Unique Code...
}
class Class2 extends AClass {
final int field;
public Class2(int f) {
field = f;
}
#Override
public int getField() {
return field;
}
// Class Unique Code...
}
Scenario 1 is shorter since the getter logic for field only needs to be specified once. Whereas in scenario 2, the getter logic must be overridden by both subclasses. I find scenario 2 to be redundant... why write the same code twice when you can use java inheritance to your advantage.
As a final note, I usually don't hold functions in fields unless totally necessary. Whenever you have a function in a field, it's usually a sign that an abstract function can be applied.
Here is your original code with my advice applied...
public abstract class MyAbstractClass<T> {
private final String type;
protected MyAbstractClass(String t) {
type = t;
}
protected abstract T applyFactoryFunction(String value);
public T doSomething(String value) { ... }
}
Hope this helped!
I learn Java at university and I have to do following excercise.
(simplified example)
import java.util.*;
public class A{
private static class B{
Integer b;
private B(int b){this.b = b;}
}
private static class B_Comparable extends B implements Comparable<B_Comparable> {
private B_Comparable(int b){super(b);}
#Override
public int compareTo(B_Comparable that) {
return this.b.compareTo(that.b);
}
}
private static class C<T> implements myList<T> { // see below
private ArrayList<T> lst = new ArrayList<>();
private static C<B_Comparable> createComparable() {
C<B_Comparable> ust = new C<B_Comparable>();
for (int i =0; i < 9; i++)
ust.lst.add(new B_Comparable(i));
return ust;
}
#Override
public T fetch(int index){
return lst.get(index);
}
}
private void test(){
C<B_Comparable> ustComparable = C.createComparable();
A result = ClassD.handle(ustComparable,3,4);
}
}
//--------------------------------------------------------
public class ClassD{
public static <T, S> T handle( S ustC, int pos1, int pos2 ){
// how can I compare elems of object ustC ?
ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
//how can I fetch obj at pos1 ?
return ustC.fetch(pos1);
}
}
//-----------------------------------------
public interface myList<T> {
T fetch(int index);
}
static method handle gets an object (ustC) which is private. How can I
use methods, compareTo and fetch for this object? I have tried parametrisation, but if its the right way, I don't know how to solve.
Thanks for any help.
As discussed in comments, ustC, by virtue of the way handle is called in this context is of type C, which implements the myList interface. This interface exposes the fetch method, and is visible to your handle method.
The modification you arrived at in your comments would allow you to call fetch:
//Solution
public class ClassD {
public static <S extends Comparable> S handle(myList<S> ustC, int pos1, int pos2 ){
int y = ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
return ustC.fetch(pos1);
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
public interface Comparable<T> {
int compareTo(T other);
}
public class Joueur implements Comparable<Joueur> {
private int points;
private int idJoueur;
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public int getIdJoueur()
{
return idJoueur;
}
public int compareTo(Joueur autre) {
// TODO Auto-generated method stub
if (points < autre.points) return -1;
if (points > autre.points) return 1;
return 0;
}
public class CollectionJoueur {
ArrayList<Joueur> j = new ArrayList<Joueur>();
public CollectionJoueur(int aIdJoueur, int aPoints)
{
Joueur ajouterJ = new Joueur(aIdJoueur, aPoints);
ajouter(ajouterJ);
}
public void ajouter(Joueur joueur)
{
j.add(joueur);
}
public iterateurJoueur creerIterateur()
{
Collections.sort(j);
Iterator<Joueur> itrJoueur = j.iterator();
while(itrJoueur.hasNext())
{
}
}
}
So here's my problem, I have been trying to do comparable sort, but in the collections sort it gave me an error of generic misbound. I have a class collection to put the player into the arraylist then i have to sort them out in ascending order.
You should implement java.lang.Comparable interface, not your own Comparable interface.
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
You'll notice that Collections.sort(..) is defined as
public static <T extends Comparable<? super T>> void sort(List<T> list) {
In other words, it expects a type that is a sub type of java.lang.Comparable. Your class is not a sub type of java.lang.Comparable. What you are trying to do with Collections.sort(..) is not possible.
Get rid of your Comparable type and use java.lang.Comparable.
Or write your own sorting method.
I have this class public class IndexedColumn extends Column<List<String>, String>. I want that class to super different objects depending on different key variable.
The following code is ok but it only have 1 super (new ClickableTextCell())
public class IndexedColumn extends Column<List<String>, String>{
private final int index;
public IndexedColumn(int index) {
super(new ClickableTextCell());
this.index = index;
}
#Override
public String getValue(List<String> object) {
return object.get(this.index);
}
public int getIndex(){
return index;
}
}
In other class
int myIndx=getIndex();
IndexedColumn nameColumn=null;
if(text.equals("clickText")){
nameColumn=new IndexedColumn(myIndx);
}
However, if i want to both super(new ClickableTextCell()) & super(new ButtonCell()) , then it got error
public class IndexedColumn extends Column<List<String>, String>{
private final int index;
public IndexedColumn(int index, int cellType) {
if(cellType==1)
super(new ClickableTextCell());
else{
super(new ButtonCell());
}
this.index = index;
}
}
So the eclipse suggested me to have another constructor like this:
public class IndexedColumn extends Column<List<String>, String>{
private final int index;
public IndexedColumn(int index) {
super(new ClickableTextCell());
this.index = index;
}
public IndexedColumn(int index, int forNothingKey) {
super(new ButtonCell());
this.index = index;
}
}
then in other class
int myIndx=getIndex();
IndexedColumn nameColumn=null;
if(text.equals("clickText")){
nameColumn=new IndexedColumn(myIndx);
}
else if(text.equals("clickButton")){
int forNoGoodReason=1;
nameColumn=new IndexedColumn(myIndx, forNoGoodReason);
}
As you can see, in order to be able to use ButtonCell column, i have to use an int forNoGoodReason variable for nothing.
Is it a good practice to do that?
or can you find a better way to fix it?
In Java, the superclass of a class is explicitly declared in the class header; e.g.
public class Foo extends Bar ... {
....
}
Every class apart from Object has exactly one superclass determined at compile time. It cannot be changed or selected dynamically / at runtime.
GWT, being based on Java and the Java type system has the same restriction.
On the other hand, you can declare a class with multiple constructors like this:
public class Bar ... {
public Bar (Integer i) { ... }
public Bar (Double d) { ... }
}
and do this:
public class Foo extends Bar ... {
public Foo (Integer i) {
super(i);
...
}
public Foo (Double d) {
super(d);
...
}
}
But, you cannot do anything like this:
public class Foo extends Bar ... {
public Foo (Integer i, Double d, boolean b) {
super(b ? i : d);
...
}
}
The problem is that the the super call in a constructor must resolve to a single constructor overload in the superclass at compile time, based on the static types of the arguments provided to the super call.
The only way to get something like this if you are going to use new to create objects is to have a unified constructor in the superclass that handles both / all cases; e.g.
public class Bar ... {
public Bar (Object o) {
if (o instanceof Integer) {
...
} else if (o instanceof Double) {
...
} // etcetera
}
}
... but that is exceedingly ugly, not to mention the fragility, and harmful coupling.
The other alternative is to use a factory method ... like this:
public class Foo extends Bar ... {
public Foo (Integer i) {
super(i);
...
}
public Foo (Double d) {
super(d);
...
}
public static Foo createFoo(Integer i, Double d, boolean b) {
return b ? new Foo(i) : new Foo(d);
}
}