abstract classes, inheritance, best way to do programm with figures - java

import java.lang.Math;
public class FiguraProba
{
public abstract class Figura {
public abstract double pole();
public abstract double obwod();
}
public abstract class Czworokat extends Figura {
public double obwod(double bok1, double bok2, double bok3, double bok4)
{
return (bok1+bok2+bok3+bok4);
}
public abstract double pole();
}
public class Kwadrat extends Czworokat {
double bok1;
public Kwadrat(double bokPodany)
{
bok1=bokPodany;
}
public double pole(double bok1) {
return bok1*bok1;
}
}
public class Prostokat extends Czworokat {
double bok1, bok2;
public Prostokat(double bokPodany1, double bokPodany2)
{
bok1=bokPodany1;
bok2=bokPodany2;
}
public double pole(double bok1, double bok2) {
return bok1*bok2;
}
}
public static void main(String args[] )
{
//System.out.println(Math.sin(90*(Math.PI/180)));
}
}
I apologize for my English and using English variable names. My goal is: I have object f.e squareExample with side 5. I want to call function to compute area from class square and call function perimeter from class quadrange to compute perimeter. Is it possible?
Compilator says: "FiguraProba.Prostokat is not abstract and does not ovveride abstract method pole() in FiguraProba.Czworokat." I understand the error but I dont know how to work out the error to achieve the goal.
Sorry for using code variables and classes in a foreign language. Here is the explanation what all the words mean:
figura - figure
kwadrat - square
czworokat - quadrangle
prostokat - rectangle
pole - area
obwod - perimeter
bok - side

The solution would be the following:
import java.lang.Math;
public class FiguraProba
{
public abstract class Figura {
public abstract double pole();
public abstract double obwod();
}
public abstract class Czworokat extends Figura {
public double obwod(double bok1, double bok2, double bok3, double bok4)
{
return (bok1+bok2+bok3+bok4);
}
public abstract double pole();
}
public class Kwadrat extends Czworokat {
double bok1;
public Kwadrat(double bokPodany)
{
bok1=bokPodany;
}
// Method without any arguments like the Figura class
// When you extend an abstract class, you have to
// implement the exact method with the exact number of arguments
// Of course you are obligated only if you can create an instance
// of that object. The perfect example when you are not obligated to
// implement a method is class Czworokat. Czworokat is not
// obligated, because you can not create an instance out of it.
public double pole() {
return bok1*bok1;
}
}
public class Prostokat extends Czworokat {
double bok1, bok2;
public Prostokat(double bokPodany1, double bokPodany2)
{
bok1=bokPodany1;
bok2=bokPodany2;
}
// Same logic applies here.
// When you extend an abstract class, you have to
// implement the exact method with the exact number of arguments
// Of course you are obligated only if you can create an instance
// of that object. The perfect example when you are not obligated to
// implement a method is class Czworokat. Czworokat is not
// obligated, because you can not create an instance out of it.
public double pole() {
return bok1*bok2;
}
}
public static void main(String args[] )
{
//System.out.println(Math.sin(90*(Math.PI/180)));
}
}
This would be what you want in case you would only use the classes properties and return the value on behalf of that. If you do want the pole methods with one and two arguments (like you have it in the code), then you would still need to remove the abstract pole method OR you would need to implement that exact method with ZERO arguments.
You can not breach the contract by NOT implementing pole with no arguments. If you need a deeper understanding about abstract classes, then I would suggest you to take a look at the official Java documentation.

If you are overriding a method from abstract class you have to write it exacly what it looks like in interface. So your method should have the same name and the same arguments.
In other worlds, you have a method with signature double pole(double bok1), but you still have to override method dobule pole();

Related

I'm trying to make a derived class method available through a base class reference

I'm trying to call a derived class method with a base class reference but I do not want to implement it in the base class or other derived classes. Only in that one derived class.
One alternative I looked into was to declare the function and base class as abstract. The only problem is if I make the base class and method abstract, I have to implement the abstract method in all of the derived classes. Is there a way to do this where I don't have to implement the abstract method in all of the derived classes and I can just define it in the class where the method makes sense? Keep in mind that I also don't want to implement method this in the base class and I want to call it through a base class reference of a derived object.
"inputSquareFt" is the function that I'm trying to call in the derived class (Landscaping) from the base class (Service) reference "newS" is main.
Thanks
//**THIS IS MY BASE CLASS**
public class Service extends Utility {
//default constructor
public Service() {
this.name = null;
this.cost = 0;
}
//constructor
public Service(String name, float cost) {
this.name = name;
this.cost = cost;
}
public int inputName() {
}
public int inputCost()
{
}
public void display() {
}
//PRIVATE DATA MEMBERS //
private String name;
private float cost;
}
public class Landscaping extends Service {
public int inputCost() {
}
**THIS IS THE FUNCTION THAT I WANT TO ONLY BE DEFINED IN THIS CLASS **
public int inputSquareFt() {
}
public final void display() {
}
private float sqFt;
private float costPerSqFt;
}
public class Main {
public static void main(String args[])
{
**BASE CLASS REFERENCE TO A DERIVED Landscaping OBJECT**
Service newS = new Landscaping();
newS.inputName();
newS.inputCost();
**inputSquareFt() IS THE FUNCTION IM TRYING TO CALL IN A DERIVED CLASS**
newS.inputSquareFt();
newS.display();
}
}
Downcast the Service reference to Landscaping to tell the compiler that you know for sure it's a Landscaping object, then it will let you call the method. If you're wrong you'll get a ClassCastException at runtime, your penalty for lying to the compiler.
((Landscaping) newS).inputSquareFt();

Do i need to implement all the methods of interface again while inheriting abstract class in Java?

I am trying to extends an abstract class which is implemented one method of interface so in my subclass i am trying to implement rest of the methods declared in interface but sub class forcing me to declare all the methods of interface, please help me to fix this, thanks in advance i have added my code below. Thanks much in advance seniors.
My code
interface xxx
{
int numbers();
String names();
Double salary();
}
abstract class GetNames implements xxx
{
public String names()
{
return "Ravi";
}
}
class Check extends GetNames
//This class forcing me to implement names also
{
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
}
public class AbsUsingInterface {
}
You only need to implement methods from Interface which have not been implemented in abstract class which is a super class for your class where you are trying to implement methods.
But looks like I see one problem in your Check class.
Your interface declares this method,
Double salary();
Where as in check class you are implementing this method,
public double sal()
So this really doesn't implement a method from interface. You need to make it same as it is in interface.
Just make method in your Check class like this,
public Double salary()
{
return 25000.00;
}
While implementing/overriding a method from superclass/interface, you should always use #Override annotation so in case any of your method signature differs, it will prompt you for error right there. And yes if you declare names() method again in your subclass Check, it will override the one in abstract class.You can do something like this in your class,
abstract class GetNames implements xxx
{
#Override
public String names()
{
return "Ravi";
}
}
class Check extends GetNames
{
#Override
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
#Override
public Double salary() {
return sal();
}
#Override
public String names() { // this overrides names() method in GetNames class
return "Check";
}
}
A concrete class extending an abstract class must provide body to all the abstract method in super class.
Methods in an interface are by default- abstract unless you provide a default body.
When an abstract class implements an interface, all those methods of an interface are inherited as it is i.e. abstract
Now for your scenario, where you have provided a body for one of the inherited method of the interface, this method is no longer abstract in the scope of 'Abstract' class. So, if a class extends this abstract class, then it need not provide a body for the above method because it is no longer abstract(They can of-course override it).
You are getting an error in Check subclass that you have defined for not inheriting salary() method, not names() method that you have already defined in GetNames abstract class
your GetNames class is implementing xxx interface but you are only implementing names()
you must implement salary method.
interface xxx
{
int numbers();
String names();
Double salary();
}
abstract class GetNames implements xxx
{
public String names()
{
return "Ravi";
}
public Double salary()
{
return null;//just return null;
}
}
class Check extends GetNames
{
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
}
or just throw NotImplementedException;

Call/Assign a variable of a Class that implements an Interface

I wrote an easy interface-inheritance example to illustrate what I'm trying to do.
interface Fruit{
public void taste();
}
class Banana implements Fruit {
public String name = "Banana";
public void taste(){
System.out.println("yummy banana!");
}
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a"+ fruit.name + "!" );
// error: name cannot be resolved or is not a field
fruit.taste();
}
}
class exec {
public static void main(String[] args) {
Lunch<Banana> bananalunch = new Lunch<>;
bananalunch.fruit = new Banana();
bananalunch.tasteit();
}
}
So Banana and Strawberry are implementing Fruit. In the class Lunch I'm trying to call the fruit name and its function taste();
While calling the Function taste works just fine, i can't call the name (see: error in the comment)
Wanted Output:
I'm going to eat a Banana!
yummy banana!
Like I said, yummy banana works but the name can't be resolved. I tried to declare "public String name = "default""; in the Fruit interface. Then you can call it, but it will always say "default" and not the name in the actual class.
Is there a way to get a member of a generic Type that implements an interface?
P.S. I need to do it like this, of course this code was only for representation but I have a much larger more complicated code in which i encountered this problem- And I don't want to restructure it if not necessary.
Thank you in advance!
Your problem is caused by trying to access an instance member directly - fruit.name - instead of via a method - fruit.getName().
If you use a getter method, the correct method will be executed and return the required output.
That said, in this particular example it would make more sense to have a single getName() method in a base class, and a single _name variable in that base class, which is initialized to a different value based on the actual type of fruit class.
On the other hand, seeing that your Fruit is an interface rather than a base class, you can have each of the classes which implement that interface have a getName() method returning a different value.
For example:
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
would become:
class Strawberry implements Fruit {
public String getName () {
return "Strawberry";
}
public void taste() {
System.out.println("yummy strawberry!");
}
}
You would have to add getName() to the interface:
interface Fruit {
public String getName();
public void taste();
}
Finally, your Lunch class becomes:
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a "+ fruit.getName() + "!" );
fruit.taste();
}
}
Case, when class implements interface, means that object of this class can do something that described in interface.
For example, every plane shape has area. So we can determine interface:
interface PlaneShape {
int getArea();
}
Area of square is product of edges. And area of circle is product of
squared radius by pi number divided by 2. So:
class Square implements PlaneShape {
public int edge = 5;
public int getArea() {
return edge*edge;
}
}
class Circle implements PlaneShape {
public int radius = 5;
public int pi = 3.14;
public int getArea() {
return radius*radius*pi/2;
}
}
Interfaces use for abstraction. AreaCalculator operates with plane shapes, so it abstracts from any specific kind of plane shapes. AreaCalculator just knows that any shape can give him area value by executing method getArea(). AreaCalculator don't know anything about special shape fields, like edge or radius.
class AreaCalculator<S implemets PlaneShape> {
public S shape;
public int calculateArea() {
shape.getArea();
}
}
By this way, in your example,Lunch<Fruittype implements Fruit> class don't know anything about fruits inner names, it doesn't "see" this fields, it only can invocate method taste(). You need to add method getName() to interface, and implement it.
On the subject of name="default" in interface. It declared in context of interface and hasn't any relation to implementations.

Java Generic Class Can't Find Method

For my CS assignment I need to write a generic Bag object that implements the container interface. The Bag should only be able to hold items that implement the Thing interface. My problem, is when I try to compile, I get the this...
Bag.java:23: error: cannot find symbol
if (thing.getMass() + weight >= maxWeight) {
symbol: method getMass()
location: variable thing of type Thing
where thing is a type-variable:
Thing extends Object declared in class Bag
the getMass() method is clearly defined in the Thing interface, but I can not get the Bag object to find it. Here are my class files...
public interface Thing {
public double getMass();
}
public class Bag<Thing> implements Container<Thing> {
private ArrayList<Thing> things = new ArrayList<Thing>();
private double maxWeight = 0.0;
private double weight = 0.0;
public void create(double maxCapacity) {
maxWeight = maxCapacity;
}
public void insert(Thing thing) throws OutOfSpaceException {
if (thing.getMass() + weight >= maxWeight) {
things.add(thing);
weight += thing.getMass();
} else {
throw new OutOfSpaceException();
}
}
}
public interface Container<E> {
public void create(double maxCapacity);
public void insert(E thing) throws OutOfSpaceException;
public E remove() throws EmptyContainerException;
public double getMass();
public double getRemainingCapacity();
public String toString();
}
I posted all of my code that i feel is relevant to save space. If the problem is difficult to locate, i can post every line. Just let me know.
There's an extra <Thing> that's confusing the compiler. Change
public class Bag<Thing> implements Container<Thing> {
to
public class Bag implements Container<Thing> {
Right now you're creating a new type variable named Thing that hides the existing Thing interface. What you're writing now is equivalent to
public class Bag<E> implements Container<E>
...just with a variable named Thing instead of E.

Which arguments for superclass constructor?

I'm studying a chapter in java related to Inheritance, and i have a few questions.
I' have basic understanding how inheritance works ( overriding methods, information hiding, how to use private fields from superclass in a subclass etc ), but i have just one problem and i hope you might help me.
When superclass have non default constructor(s) - without parameters, that means that in a subclass i have to create new constructor (it can be default - without parameters ), but in a first statement must be superclass constructor call.
Ok, so far so good. I understand so far. In subclass you must call superclass constructor, matching any of constructors parameters.
But lets check following code: (Superclass)
public class Vehicle {
private int numOfWheels;
private double avgGallonsPerMile;
public Vehicle(int numOfWheels, double avgGallonsPerMile) {
this.numOfWheels = numOfWheels;
this.avgGallonsPerMile = avgGallonsPerMile;
}
}
And another Subclass code:
public class Car extends Vehicle{
public Car(double avgGallonsPerMile) {
super(What should i write here?, avgGallonsPerMile);
//force numOfWheels to 4;
}
}
Here is the exercise for subclass:
Each subclass
contains a constructor that accepts the miles-per-gallon value as an argument and
forces the number of wheels to the appropriate value—2 for a MotorCycle and 4 for
a Car.
In subclass constructor i don't need numOfWheels field, because i will force it to 4 ( for car ) and 2(for motorbike) anyway.
But stil i need that data for superclass anyway. Where to get that data? What should as first parameter in call to superclass constructor.
But still this isn't the lonely case. I got lots of exercises that i don't need certain data in subclass constructor as parameters, BUT still i need them in superclass constructor call.
What should i do in such cases ?
I really hope you understood me, what i want to tell. It's kinda difficult.
If its anyway the same 4 for cars and 2 for motorcycles than make if fix!
super(4, avgGallonsPerMile);
or the better way - declare a constant:
private static final int NUM_OF_WHEELS = 4;
..
super(Car.NUM_OF_WHEELS, avgGallonsPerMile);
If you don't need a field in a super class then chances are it shouldn't be there. Instead you can do the following.
public abstract class Vehicle {
private final double avgGallonsPerMile;
public Vehicle(double avgGallonsPerMile) {
this.avgGallonsPerMile = avgGallonsPerMile;
}
public double getAvgGallonsPerMile() { return avgGallonsPerMile; }
public abstract int getNumOfWheels();
}
public class Car extends Vehicle{
public Car(double avgGallonsPerMile) {
super(avgGallonsPerMile);
}
public int getNumOfWheels() { return 4; }
}
public class Bicycle extends Vehicle{
public Bicycle (double avgGallonsPerMile) {
super(avgGallonsPerMile);
}
public int getNumOfWheels() { return 2; }
}
public class Tricycle extends Vehicle{
public Tricycle (double avgGallonsPerMile) {
super(avgGallonsPerMile);
}
public int getNumOfWheels() { return 3; }
}
BTW: Your car must be really inefficient if it uses gallons per mile of fuel.
Very simple: if the number of wheels on a Car is always 4, them simply pass the value 4:
public Car(double avgGallonsPerMile) {
super(4, avgGallonsPerMile);
// ...
}

Categories

Resources