Creating a Generic for a Class - java

Assuming you have a class named Rational where each object contains two ints representing the numerator and the denominator, write the class definition line if you wanted to indicate that it would implement the generic interface Comparable and write the body of the required method with the signature:
public int compareTo(Object other);
so that it will only return -1 or 0 or +1 based on the relative order of the two objects based on the numerators and denominators.
I don't understand how to create a generic for Rational1, that takes the two integers (numer, denom). Any help with this, will be greatly appreciated. This is my Rational1 class so far:
public class Rational1 implements Comparable<Rational1> {
private int numer;
private int denom;
public Rational1(int numer,int denom){
this.numer = numer;
this.denom = denom;
}
public Rational1(Rational1 po){
po = new Rational1(numer, denom);
}
public int compareTo(Object other){
other = new Rational1(numer, denom);
if(numer>denom){
return 1;
}
else if(numer<denom){
return -1;
}
else{
return 0;
}
}
}
And this is my interface:
public interface Comparable<Rational1> {
public int compareTo(Object other);
}
And Lastly, my main which gives me an error on the last line when I call the generic:
public class Rational {
public static void main(String[] args){
Rational1 rational = new Rational1(4,3);
Comparable<Rational1> ration = new Comparable<Rational1>();
}
}

First things first, even if it is not direclty related with the question your constructor
public Rational1(Rational1 po) {
po = new Rational1(numer, denom);
}
is a complete nonsense. It should be
public Rational1(Rational1 po) {
this(po.numer, po.denom);
}
Your main method is also wrong, you have to provide a concrete class not an interface (an interface can never be instantiated) :
public static void main(String[] args){
Rational1 rational = new Rational1(4,3);
Comparable<Rational1> ration = new Rational1();
}
Finally, your implementation of the comparison is wrong because :
it's mathematically wrong
the signature of compareTo is not correct. It should be int compareTo(Rational1 that).
you are constructing a new instance instead of considering your parameter. It should be
#Override
public int compareTo(Rational1 that) {
return Integer.compare(numer*that.denom, that.numer*denom);
}
Always use #Override when implementing an abstract class/interface to make sure you are indeed overriding the abstract members.

Comparable<Rational1> is an interface. It has no constructor. You can't instantiate an instance of it. I assume this is the source of the error you are currently hitting, although you don't specify what the error is.
From the problem description (first paragraph), it's not clear what you are trying to do in main() at all. Your main goal is to write a definition for the compareTo() method, which you've done.
That said, the compareTo() method that you have written is nonsensical. You need to think (or read) more about what a rational number is and how you would go about comparing two rational numbers with one another.

Related

Is it bad practice to override a function only to add a little bit of functionality by calling super?

If I have a super class BaseClass and a subclass SubClass, and I want some of the subclass's functions to be slightly different, is it bad practice to just override the original, call super, and tack on a little extra functionality?
For example: (pseudo code)
public class BaseClass{
int fooA();
int fooB();
int fooC();
}
public class SubClass extends BaseClass{
#Override
int fooB(){
int temp = super.fooB();
temp += 1;
return temp;
}
#Override
int fooC(){
System.out.println("I'm doing something extra in fooC!");
return super.fooC();
}
}
I'm trying to prevent code duplication, but I kind of feel like I'm doing something wrong or forgetting some basic OOP stuff, so I thought I'd ask if this was bad practice. It's been a while since I've done inheritance; thanks for any insight.
Instead of inheriting you can do the following:
public class SubClass implements MyInterface {
private MyInterfaceBasicImpl base;
int fooB(){
int temp = base.fooB();
temp += 1;
return temp;
}
int fooC(){
System.out.println("I'm doing something using in fooC in base object!");
return base.fooC();
}
}
It's an easy example of Composition pattern. As there is no multiple inheritance in Java it'll keep your code Open for improvements.
The ability of a subclass to override a method allows a class to
inherit from a superclass whose behavior is "close enough" and then to
modify behavior as needed. The overriding method has the same name,
number and type of parameters, and return type as the method that it
overrides. An overriding method can also return a subtype of the type
returned by the overridden method. This subtype is called a covariant
return type.
Hopefully this provides an answer to your question.
https://docs.oracle.com/javase/tutorial/java/IandI/override.html
You can do what you suggest, is an option. But, what happen if you have for example 3 classes which do the same? You're still repeating code and logic, because in each of them you will call super. What you can do in that case is implement a template method pattern. If you haven't read about it, it means to define a method in the super class as abstract, use it there and then define it in the subclasses. Following your example, it could look something like this:
public class BaseClass{
int fooA();
int fooB();
int fooC(){
//here goes the common logic;
this.printWhatItHasToPrint();
}
void printWhatItHasToPrint() {}; //if the class is abstract you may define it as abstract
}
public class SubClass1 extends BaseClass{
#Override
int fooB(){
int temp = super.fooB();
temp += 1;
return temp;
}
#Override
void printWhatItHasToPrint(){
System.out.println("I'm doing something extra in fooC!");
}
}
public class SubClass2 extends BaseClass{
#Override
void printWhatItHasToPrint(){
System.out.println("I'm doing something extra in fooC, and I'm another class!");
}
}
I think it might be correct approach, but from my experience it's more readable and convenient to make one abstract class with common functions implemented and then have two subclasses to extend it in order to implement different functions, like that:
public abstract class BaseClass {
public void fooA() {
System.out.println("Some common function");
}
public void fooB() {
System.out.println("Another common function");
}
public abstract int fooC();
}
public class SubClass1 extends BaseClass {
#Override
public int fooC() {
return 0;
}
}
public class SubClass1 extends BaseClass {
#Override
public int fooC() {
return 1;
}
}
This way it will be much easier to navigate through larger projects and feels more natural

Is there a certain benefit in declaring an object using a class and assign it to another class?

During a Java course in my University we teach this example. While I certainly understand how this works, I fail to imagine a real life example where this practice might be useful. In my eyes it makes the code harder to understand. More specifically, is there a certain benefit in declaring an object using a class and assign it to another class (Small smallBig = new Big();) and can you give me a simple scenario where this practice might be useful?
The code:
public class Small {
public int value;
public Small() {value = 10;}
public int getValue() {return value;}
}
public class Big extends Small {
public int value;
public Big() {value = 40;}
public int getValue() {return value-10;}
}
public class Main {
public static void main (String args[]) {
Small small = new Small();
Small smallBig = new Big();
Big big = new Big();
System.out.println(small.getValue());
System.out.println(smallBig.getValue());
System.out.println(big.getValue());
System.out.println(small.value);
System.out.println(smallBig.value);
System.out.println(big.value);
small = (Small) big;
System.out.println(small.getValue());
System.out.println(small.value);
big = (Big) small;
System.out.println(big.getValue());
System.out.println(big.value);
}
}
The output:
10
30
30
10
10
40
30
10
30
40
Creating a method that operates on both Bigs and Smalls will help to illustrate the point better.
Assuming the same class definitions you already used in the question, you can create a method that prints both getValue() and value. Because Big extends Small, you need only one method.
public void printValues(Small val) {
System.out.println("getValue() == " + val.getValue());
System.out.println("value == " + val.value);
}
If you didn't have that relationship, and ability to assign Big objects to Small variables (remember: passing a value to a method is the same as assigning a variable), you'd need to have two different methods to handle this situation.
It helps to think of the extends keyword as meaning A Big is a more specific type of Small. In general, it's best to write methods that handle things using the least specific type that you can, because it will allow that method to handle situations you haven't even imagined yet.
For example, suppose that somewhere down the line, somebody decided to write
class Medium extends Small {
public Medium() {value = 20;}
public int getValue() {return value-5;}
}
The printValues() method can already handle this class, even though we didn't know about Mediums when we wrote it.
I think in this senario it'd be useful:
public class Person{
Mobility mobility;
Person(Mobility mobility){this.mobility = mobility;}
}
public class Mobility{
int speed;
public Mobility(int speed){this.speed = speed;}
}
public class Car extends Mobility{
public Car(int speed){super(speed);}
}
public class Main {
public static void main (String args[]) {
Car ferrari = new Car(1000);
Person john = new Person(ferrari);
}
}
Hope i could help you.
Well in this case you are using getValue as Template method "http://en.wikipedia.org/wiki/Template_method_pattern"
Let take you example with little twist
public class Small {
public int value;
public Small() {value = 10;}
public int getValue() {// this method fetches data from database}
}
public class Big extends Small {
public int value;
public Big() {value = 40;}
public int getValue() {//this method fetches data from xml}
public class Big2 extends Small {
public int value;
public Big() {value = 40;}
public int getValue() {//this method fetched data from some server}
}
As u can see the implementation of getValue is changing. Each sub class provides its own implementation of getValue.
Thus it gives my super class an opportunity to use different implementation of this method at run time (in you case). I Hope it makes it clear. Have a look at Template method pattern , you will get a better idea.

instantiating a class from array of interfaces

SEE THE EDIT HALFWAY DOWN THE POST.
I'm new to java and all the formal declarations of inheritance are getting me a little confused.
I have a interface like so:
public interface A{
public void one();
public void two();
}
and then I have two classes like so:
public class B implements A{
private int num;
public void one(){
...
}
public void two(){
...
}
public B(){
this.num = 1;
}
}
public class C extends B{
public C(){
super();
}
}
then I have a driver class like so:
public class Driver{
public static void main(String [] args){
A a_array[] = new A[5];
for(int i=0; i<6; i++){
if(i%2==0){
a_array[i] = new B();
}
else{
a_array[i] = new C();
}
}
}
}
Basically, given an array of interfaces I am trying to implement various classes that implement that interface.
Now my guess is there are several things wrong with this implementation, but I seem unable to sniff them out. Primarily right now I am getting the error 'B() is not abstract and does not implement method one()'.
EDIT:
alright lets try this...
the interface:
public interface Shape{
public double calcAread();
public double calcPerimeter();
}
the implementing class:
public class Rectangle implements Shape{
private double length;
private double width;
public double calcArea(){
return this.length*this.width;
}
public double calcPerimeter(){
return (this.length*2)+(this.width*2);
}
public Rectangle(double length, double width){
this.length=length;
this.width=width;
}
// then some other methods including the set methods
}
the extending class:
public class Square extends Rectangle{
public Square(){
super();
}
public Square(double sideLength){
super.setLength(sideLength);
super.setWidth(sideLength);
}
// some more methods
}
I can't think of very much more that would be useful other than to mention that there are other inheriting and extending classes off of these but they follow exactly the same design and sentax.
No errors when I compile shape, but the 'Rectangle is not abstract and does not override abstract method calcAread() in Shape' error is tripped when I compile the Rectangle class.
Hopefully this will be more enlightening.
Thanks
the only problem I see in the code is that the i<5 instead if i<6. array size is 5 and the initialization is set to i=0. (loop iterations should be 0,1,2,3,4, otherwise u will get ArrayIndexOutOfBound exception)
I compiled the code and its running fine.
What you've provided as example code will work just fine. My suspicion is that your exact code and your example code differ.
Without seeing the exact error message and B class it's hard to say, but I'm willing to bet you have either a return value or parameter difference between the definition of one in your interface and your one in your implementation.
Edit: Here's what I see as the problem. Your interface's method is called "calcAread". Is that d supposed to be on the end?
public double calcAread();
Because it's missing inside Rectangle
public double calcArea()
That's going to cause a problem. It makes me wonder how #Zohaib managed to compile it actually!

generics calling constructor

I am trying to do something I would not normally do, it is a bit odd, but I'd like to make it work. Essentially I have a factory that has to create objects by calling the constructor with different types of data (A and B take different types in the code below). I seem to have gotten my self stuck going down the generics route (I do need the code to be as compile time typesafe as possible). I am not opposed to writing the code differently (I'd like to keep the idea of the factory if possible, and I do not want to have to add in casts - so the "data" parameter cannot be an "Object").
Any thoughts on how to fix the code with generics or an alternative way of doing it that meets my requirements?
(Technically this is homework, but I am the instructor trying out something new... so it isn't really homework :-)
public class Main2
{
public static void main(String[] args)
{
X<?> x;
x = XFactory.makeX(0, "Hello");
x.foo();
x = XFactory.makeX(1, Integer.valueOf(42));
x.foo();
}
}
class XFactory
{
public static <T> X<T> makeX(final int i,
final T data)
{
final X<T> x;
if(i == 0)
{
// compiler error: cannot find symbol constructor A(T)
x = new A(data);
}
else
{
// compiler error: cannot find symbol constructor B(T)
x = new B(data);
}
return (x);
}
}
interface X<T>
{
void foo();
}
class A
implements X<String>
{
A(final String s)
{
}
public void foo()
{
System.out.println("A.foo");
}
}
class B
implements X<Integer>
{
B(final Integer i)
{
}
public void foo()
{
System.out.println("B.foo");
}
}
I don't see a way to make it work. I don't really think it should work either. When calling your makeX() function the calling code needs to know what integer parameter corresponds to what type of data to pass in. IOW, your abstraction is very leaky in the first place, and what you're really implementing is a rudimentary form of polymorphism, which you might as well use method overloading for, i.e.:
X makeX(String data) {
return new A(data);
}
X makeX(Integer data) {
return new B(data);
}
Of course it's a toy problem and all that. One way to make it work would be to make the client aware of implementation classes and add a Class<T> argument that you instantiate through reflection. But I suppose that would be kind of defeating the purpose.
I don't think what you're trying to do is possible without casting.
With casting, you have two options
if(i == 0)
{
x = new A((Integer)data);
}
else
{
x = new B((String)data);
}
}
or
class A
implements X<String>
{
A(final Object s)
{
}
}
...
class B
implements X<Integer>
{
B(final Object i)
{
}
}
Probably the closest thing you could get whilst retaining static type safety and having lazy construction is:
public static void main(String[] args) {
X<?> x;
x = aFactory("Hello").makeX();
x.foo();
x = bFactory(42).makeX();
x.foo();
}
private static XFactory aFactory(final String value) {
return new XFactory() { public X<?> makeX() {
return new A(value);
}};
}
public static XFactory bFactory(final Integer value) {
return new XFactory() { public X<?> makeX() {
return new B(value);
}};
}
interface XFactory() {
X<?> makeX();
}
So we create an instance of an abstract factory that creates the appropriate instance with the appropriate argument. As a factory, the product is only constructed on demand.
Clearly something had to give. What would you expect XFactory.makeX(1, "Hello") to do?
This is not possible without casting. As I have said elsewhere - generics don't remove the need for casting, but they mean that you can do all the casting in one place.
In the setup you describe, the factory method is exactly where all the under-the-hood work takes place. It's the spot where your code tells the compiler "I know you don't know what these types are, but I do, so relax.
It's entirely legit for your factory method to know that if i==1, then the data must be be of type Integer, and to check/enforce this with casting.

Java overloading vs overriding

Hi I just want to make sure I have these concepts right. Overloading in java means that you can have a constructor or a method with different number of arguments or different data types. i.e
public void setValue(){
this.value = 0;
}
public void setValue(int v){
this.value = v;
}
How about this method? Would it still be considered overloading since it's returning a different data type?
public int setValue(){
return this.value;
}
Second question is: what is overriding
in java? Does it relate to inheritance. Let's I have the following:
public class Vehicle{
double basePrice = 20000;
//constructor defined
public double getPrice(){
return basePrice;
}
}
public class Truck extends Vehicle{
double truckPrice = 14000;
//constructor defined
public double getPrice(){
return truckPrice;
}
}
So now let's say I have the following
Truck truck = new Truck();
if I call
truck.super.getPrice()
this would return the price from the Vehicle class, 20,000
if I call
truck.getPrice()
this would return the price in the truck class, 14,000
Is my knowledge correct for both questions?
You are basically correct. Overloading is having multiple methods in a single class where the method has the same name. However, the return value is not seen as part of the signature of the method. Thus, you cannot overload a method by changing only the return value. You cannot have the following code, from your example:
public void setValue() {
this.value = 0;
}
public int setValue() {
return this.value;
}
This will fail to compile.
As Rob identified, I believe you mean overriding, and you have that correct. Note with overriding, you cannot change the return type. As of Java 5, you can return a derived type of what the base class method returned. Before Java 5, it must be the identical type. That is, you cannot do the below until Java 5 and later:
public class AnimalNoise {}
public class Miaw extends AnimalNoise {}
public class Animal {
public AnimalNoise makeNoise() {
return new AnimalNoise();
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
However, even in Java 5 and later, you cannot do the following:
public class Animal {
public String makeNoise() {
return "silence";
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
public class Miaw {}
Finally, a big difference between overloading and overriding that is often overlooked is that overloading is decided at compile time and overriding is decided at runtime. This catches many people by surprise when they expect overloading to be decided at runtime.
Correct; overloading is providing multiple signatures for the same method.
Overriding, which is what I think you mean by "overwriting" is the act of providing a different implementation of a method inherited from a base type, and is basically the point of polymorphism by inheritance, i.e.
public class Bicycle implements Vehicle {
public void drive() { ... }
}
public class Motorcycle extends Bicycle {
public void drive() {
// Do motorcycle-specific driving here, overriding Bicycle.drive()
// (we can still call the base method if it's useful to us here)
}
}
what you have described is correct.
For more clarification take a look at polymorphism concept. The Wikipedia has a good article
http://en.wikipedia.org/wiki/Polymorphism#Computing
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

Categories