I get an error for: a.getLargest(a.create());
in the main method. It says that
I have to implement the method in Geo
public abstract class Measurable<T> {
abstract double getMeasure();
public static <T extends Measurable<T>> T getLargest(ArrayList<T> objects){
T largest = objects.get(0);
for(int i = 0; i < objects.size(); i ++){
if(largest.getMeasure() == objects.get(i).getMeasure()){
largest = objects.get(i);
}
}
return largest;
}
}
And in a separate file:
import java.util.ArrayList;
import java.util.Collection;
public class Test extends Measurable {
private Geo test;
private static ArrayList<Geo> object;
public Test(){
test = new Geo();
object = new ArrayList<Geo>();
}
public double getMeasure() {
double size = 0;
for(int i = 0; i < object.size(); i++){
size = object.get(i).getArea()*object.get(i).getPerimeter();
}
return size;
}
public ArrayList<Geo> create(){
for(int i = 0; i < 10; i++){
test = new Geo(i, i);
object.add(test);
}
return object;
}
public static void main(String[] args){
Test a = new Test();
a.getLargest(a.create());
}
}
And thats the GeoClass
public class GeometricObject extends Measurable<GeometricObject>{
It seems that you don't understand what is meant by "implementing" an interface. Your Test class implements Measurable in a non-generic way. So actually you are implementing Measurable<Object>. So far so good, but then you created a Geo object. In your question, you did not show that Geo implements Measurable<Geo>, so I assume it is not. If Geo did not implement Measurable<Geo>, then the call to getLargest would fail because getLargest calls getMeasure which most likely does not exist in Geo. Instead, you should implement Measurable<Geo> in Geo class.
public class Geo implements Measurable<Geo> {
public double getMeasure () {
//some code
}
//other code
}
I guess your confusion here is might be that you think when Test implements an interface, all its members implement it. But that is not true, ok?
And another thing to remember is that when you don't specify a generic type argument, it defaults to Object not the type implementing the interface!
Related
Hello Stackoverflowers,
Imagine the following Base class
import java.util.ArrayList;
public class Array
{
private ArrayList<Object> a = new ArrayList<Object>();
public void add(Object element)
{
a.add(element);
}
public void addAll(Object elements[])
{
for (int i = 0; i < elements.length; ++i)
a.add(elements[i]); // this line is going to be changed
}
}
And here’s the Derived class:
public class ArrayCount extends Array
{
private int count = 0;
#Override
public void add(Object element)
{
super.add(element);
++count;
}
#Override
public void addAll(Object elements[])
{
super.addAll(elements);
count += elements.length;
}
}
The Array add() adds an element to a local ArrayList.
The Array addAll() calls the local ArrayList add for each element.
The ArrayCount add() calls its parent’s add() and then increments the count.
The ArrayCount addAll() calls its parent’s addAll() and then increments the count by the number of elements.
Now for the breaking change. The commented line of code in the Base class is changed to the following:
public void addAll(Object elements[])
{
for (int i = 0; i < elements.length; ++i)
add(elements[i]); // this line was changed
}
Now ArrayCount addAll() calls its parent’s addAll() which internally calls the add() which has been overriden by the Derived class.
The author of the Derived class must know how the Base class has been implemented. And they must be informed about every change in the Base class since it could break their Derived class in unpredictable ways.
I'm looking for a correct way to implement this that would respect black box programming concept. Because this exemple force the writter of the derivated class to know how the base class is implemented and know every change
I assume by "Black Box" you mean: "Implementer of the derived class must not know about the implementation details of the base class Array". I would opt for a decorator using delegation as probably being the better approach:
public class ArrayCount {
private int count = 0;
private Array a;
public ArrayCount(Array a) {
this.a = a;
}
public void add(Object element) {
a.add(element);
++count;
}
public void addAll(Object elements[]) {
a.addAll(elements);
count += elments.length;
}
}
Note: I left out input param checking for brevity.
If both Array and ArrayCount implement the same interface, e.g. IArray, you can still use the classes interchangeably:
interface IArray {
public void add(Object element);
public void addAll(Object elements[]);
}
...
Array implements IArray {...}
ArrayCount implements IArray {...}
When you use the Black box approach you just call method of an object and so you don't care about how it is implemented.
The public method of a Class is a contract that define what you provide and what you get.
The developer that maintain the Class could change anything but the contract or the method signatures.
If you extend a Class, and you're going to override a method or more methods, than you should care about the Class implementation, as you are going to specialize some behaviors of the Class.
To have a clean separation of different classes that have same interface, you should use the java interface, so each developer could do the own implementation of the business logic.
You could design a Class to be extendable from someone else, when you know that some method could be specialized.
But if you don't want that, you could decide that the method could not be overridden by defining those method final.
In this way you are telling to other developers that will use your code that you don't want to extend some behaviors.
Mark the base class methods as final but include supporting methods for extension.
import java.util.ArrayList;
public class Array {
private final ArrayList<Object> a = new ArrayList<Object>();
public final void add(Object element) {
a.add(element);
afterAdd(element);
}
public final void addAll(Object[] elements) {
for (Object element : elements) {
a.add(element);
}
afterAddAll(elements);
}
protected void afterAddAll(Object[] elements) {
return;
}
protected void afterAdd(Object element) {
return;
}
}
so a subclass can only override the support methods
public class ArrayCount extends Array {
private int count = 0;
#Override
protected void afterAdd(Object element) {
++count;
}
#Override
protected void afterAddAll(Object[] elements) {
count += elements.length;
}
}
After reading through the Generics info I am attempting a simple sample and encountering the following error.
MyClass.java:32: error: cannot find symbol
System.out.println("X = " + temp.x);
^
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
1 error
Without the reference to "temp.x" it compiles which leads me to believe the definition is correct but possibly the way the variable is referenced is the issue. Or it could be the actual implementation is wrong. Not sure.
The main class has a method which can be called by either of the 2 inner classes. When called, the method attempts to access the variable specific to the inner class that called it.
public class MyClass {
public class InnerClass1 {
int x = 100;
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 {
int x = 200;
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
MyClass x = new MyClass();
}
private <T> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
^^^^^^^^^^^^^^^^
Without further specification, e.g. <T extends InnerClass1>, the only thing that is known about T within that method is that it extends Object, and for Object, the attribute x is not defined.
Maybe you should define a common super-class for those two classes, and declare x in that super-class.
In order to get the value x from each class dynamically, you can define a common interface or abstract class for InnerClass1 and InnerClass2 to implement or extend. This allows the inheritance of methods and variables. Seeing that both holds a value of type T, let us create an interface called ValueHolder<T>:
interface ValueHolder<T> {
public T getValue();
}
Both the InnerClass1 and InnerClass2 will need to implement this interface:
public class InnerClass1 implements ValueHolder<Integer> {
private int x = 100;
#Override
public Integer getValue() {
return this.x;
}
}
public class InnerClass2 implements ValueHolder<String> {
public String x = "200";
#Override
public String getValue() {
return this.x;
}
}
As you can see, InnerClass1 implements ValueHolder<Integer>, meaning the inherited getValue methods return type will be Integer. The same goes for InnerClass2, which implements ValueHolder<String>.
Change your tryThis as follows:
private <T> void tryThis(ValueHolder<T> temp) {
System.out.println("Value = " + temp.getValue());
}
Now each value can be printed like this:
Generics g = new Generics();
g.tryThis(new InnerClass1());
g.tryThis(new InnerClass2());
Output:
X = 100
X = 200
T in
private <T> void tryThis(T temp)</code>
is just a placeholder for any class. The compiler knows nothing more about it, so it knows nothing about the symbol x as well.
To accomplish what you are trying to do, you would need something like this:
public class Generics {
abstract class MyClass {
int x;
}
public class InnerClass1 extends MyClass {
InnerClass1() {
super.x = 100;
}
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 extends MyClass {
InnerClass2() {
super.x = 200;
}
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
Generics x = new Generics();
x.new InnerClass1().runThis();
x.new InnerClass2().runThis();
}
private <T extends MyClass> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
However, you would not need Generics for this specific case:
private void tryThis2(MyClass temp) {
System.out.println("X = " + temp.x);
}
would accomplish the same.
Generics are very complex, although they look easy to use.
SO,letsay we have a bicycle superclass with cadence 0 and 3 subclasses.I want the "trotineta" sbuclass to have cadence 5 while the other 2 subclasses cadence remains 0.
Why isnt this working?
class Trotineta extends Bicycle{
Bicycle.cadence = 5;
}
You haven't shown the definition of Bicycle.cadence, but based on the syntax, I'm assuming it's a static member. If you change a static member of the base class, all instances of all sub-classes will be affected by this change, since a static member has a single value for all instances of the class.
Now, if cadence wouldn't be static, you can give it a different value in the constructor of Trotineta (assuming the sub-class has access to that member).
public Trotineta ()
{
cadence = 5;
}
This would be somewhat wasteful, though, since each instance of Bicycle would have its own cadence member.
You can create getter and setter or just use word super
public class TestONE extends TestTWO {
{
super.gg = 4;
}
public static void main(String[] args) {
System.err.println(new TestONE().gg);
}
}
class TestTWO {
static int gg = 0;
}
or
public class TestONE extends TestTWO {
public static void main(String[] args) {
TestONE.setGg(5);
System.err.println(new TestTWO().gg);
}
}
class TestTWO {
protected static int gg = 0;
public static int getGg() {
return gg;
}
public static void setGg(int gg) {
TestTWO.gg = gg;
}
}
class Bicycle{
int cadence = 0;
/* since no access modifier is mentioned, by default cadence becomes
package private ie; it cannot be accessed outside the package
in which it is defined now*/
}
class Trotineta extends Bicycle{
Bicycle.cadence = 5;
/* you cannot do this as cadence is not a static
attribute of class Bicycle*/
}
// Below is one of the possible solutions
class Trotineta extends Bicycle{
/*below code can also be written in a method but not outside as you have
written in your example code*/
{
this.cadence = 5;
//here 'this' is the current instance of Trotineta
}
}
I'm trying to create a generic class that compares objects in an array list and returns the largest. My issue is that I'm not quite sure I understand completely how generics work.
Measurable:
import java.util.ArrayList;
/**
Describes any class whose objects can be measured.
*/
public abstract class Measurable<T>{
abstract double getMeasure();
public static <T extends Measurable<T>> T getLargest(ArrayList<T> objects){
T largest = objects.get(0);
for(int i = 0; i < objects.size(); i ++){
if(largest.getMeasure() == objects.get(i).getMeasure()){
largest = objects.get(i);
}
}
return largest;
}
}
Box:
import java.awt.Rectangle;
import java.util.ArrayList;
public class Box extends Measurable {
private Rectangle box;
private static ArrayList<Rectangle> rectangles;
public Box(){
box = new Rectangle();
rectangles = new ArrayList<Rectangle>();
}
public ArrayList<Rectangle> create(){
for(int i = 0; i < 10; i++){
box = new Rectangle((int) Math.random(), (int) Math.random());
rectangles.add(box);
}
return rectangles;
}
#Override
public double getMeasure() {
double area = 0;
for(int i = 0; i < rectangles.size(); i++){
area = rectangles.get(i).getWidth()*rectangles.get(i).getHeight();
}
return area;
}
public static void main(String[] args){
Box b = new Box();
b.getLargest(b.create());
}
}
I'm coming across an issue where it says "The method getLargest(ArrayList) in the type Measurable is not applicable for the arguments (ArrayList)" but shouldn't I be able to use any object for the getLargest class?
As you wrote it, getLargest expects the objects passed to it in the List to implement Measurable, but java.awt.Rectangle does not.
When you write
public static <T extends Measurable<T>> T getLargest(ArrayList<T> objects){
that declares a T that is different, but named the same, as the T in the Measurable class as a whole, which is likely to lead to total confusion.
If you actually replace T with Rectangle in your code, you can see that you're trying to call Rectangle.getMeasure(), which is a method that does not exist.
I am not really sure where generics come into play here. It seems like you want to make a bunch of shapes that are derived from a base class Measurable. You also want the abstract class to hold some code for working with Measurable subclasses. Basically you need to make a subclass that implements Measurable. I think what you want a Box class like the one below.
public class Box extends Measurable {
private double width;
private double height;
public Box(double width, double height){
this.width = width;
this.height = height;
}
public double getMeasure() {
double area = width*height;
return area;
}
}
I am new to design patterns and I was asked to print numbers from 1 to 10 using decorator pattern. I am sorry if this is trivial but I need to learn. This is what I have so far:
Interface
public interface NextNumber {
public int getNextNumber(int n);
}
Abstract Class
abstract public class PrintNumbers implements NextNumber {
protected final NextNumber next;
protected int num;
public PrintNumbers(NextNumber next, int num)
{
this.next = next;
this.num = num;
}
public int getNextNumber(int num)
{
return num+1;
}
}
DecoratorClass
public class DecoratorCount extends PrintNumbers {
public DecoratorCount(NextNumber next, int num)
{
super(next, num);
}
public static void main(String[] args)
{
int i = 0;
}
}
Not sure how to proceed or even if I am going the right way. Could someone shed some light?
First the decorator class does not have to extend the class that decorates but implements the same interface.
Look at this Wikipedia page.
So you can correct your decorator like this:
// The interface
public interface NextNumber {
public int getNextNumber();
}
// The class to decorate
public class PrintNumbers implements NextNumber {
protected int num;
public PrintNumbers(int startFrom)
{
this.num = startFrom;
}
public int getNextNumber()
{
return num++;
}
}
// The abstract decorator
public abstract class DecoratorCount implements NextNumber {
private PrintNumbers pn;
public DecoratorCount(PrintNumbers pn)
{
this.pn = pn;
}
}
Then for example you can multiply number by 2.
public class DoubleDecoratorCount extends DecoratorCount {
public DecoratorCount(PrintNumbers pn)
{
super(pn);
}
public int getNextNumber()
{
return pn.getNextNumber() * 2;
}
}
And you can test decorator in this way
public class Test {
public static void main (String[] args) {
PrintNumbers pn = new PrintNumbers(0);
DoubleDecoratorCount decorator = new DoubleDecoratorCount(pn);
for (int i = 0 ; i < 5 ; ++i)
System.out.println("value: " + decorator.getNextNumber());
}
}
At this point you can write all decorators you need:
To multiply by 3;
To write results in letter;
To write results in hex;
Etc...
First, you need something that could need some decoration, then you need a decorator for that something. Both classes, the base class and the decorator are concrete classes and can be used directly.
Decorating a counter from 1 to 10 doesn't make much sense (numbers are always beautiful ;) ). But you could implement a basic class that prints the numbers unformatted and then implement a decorator, that adds some beauty to the printed result.