I am learning Java and don't understand why this code generates the following error: "ArrayListClass is abstract; cannot be instantiated. Help would be appreciated.
import java.util.*;
public class ArrayListClass {
protected Object[] list;
protected int maxSize;
protected int length;
public ArrayListClass() {
maxSize = 100;
length = 0;
list = new Object[maxSize];
}
public ArrayListClass(int size) {
maxSize = size;
list = new Object[maxSize];
length = 0;
}
public boolean isEmpty() {
return length == 0;
}
public boolean isFull() {
if (length == maxSize)
return true;
else
return false;
}
public int listSize() {
return length;
}
public int maxListSize(){
return maxSize;
}
public void print() {
System.out.print("The list contains:");
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public boolean isItemAtEqual(int location, Object item) {
return (list[location].equals(item));
}
public void insertEnd(Object item) {
if(!isFull())
list[length++] = item;
}
public static void main(String [] args) {
ArrayListClass dac = new ArrayListClass(5);
dac.insertEnd(4);
dac.insertEnd(5);
dac.insertEnd(6);
dac.print();
System.out.println("dac.isItemAtEqual(0,9)"+dac.isItemAtEqual(0,9));
System.out.println("dac.isItemAtEqual(1,9)"+dac.isItemAtEqual(1,9));
}
}
You can not instantiate any abstract class in any programming language. Basic construct of abstract is, it is merely blueprint, not a real object. It provides the template of a class and will provide the form or outline of the class to the concrete classes that implement the class ('extend' the class...)
So you can not instantiate ArrayListClass, as this gives a blueprint. If you extend this class say DerievedArrayListClass extends ArrayListClass, then you will be able to instantiate DerievedArrayListClass .
package com;
abstract class ArrayListClass{
protected Object [] list;
protected int maxSize;
protected int length;
public ArrayListClass(){
maxSize = 100;
length = 0;
list = new Object [maxSize];
}
public ArrayListClass(int size){
maxSize=size;
list=new Object [maxSize];
length=0;
}
public boolean isEmpty(){
return length==0;
}
public boolean isFull(){
if(length==maxSize)
return true;
else
return false;
}
public int listSize(){
return length;
}
public int maxListSize(){
return maxSize;
}
abstract void print();
public boolean isItemAtEqual(int location, Object item)
{
return (list[location].equals(item));
}
public void insertEnd(Object item){
if(!isFull())
list[length++] = item;
}
}
public class ArrayListClassImpl extends ArrayListClass{
public ArrayListClassImpl(int i) {
super(i);
}
public void print(){
System.out.print("The list contains:");
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public static void main(String [] args){
ArrayListClass dac = new ArrayListClassImpl(5);
dac.insertEnd(4);
dac.insertEnd(5);
dac.insertEnd(6);
dac.print();
System.out.println("dac.isItemAtEqual(0,9)"+dac.isItemAtEqual(0,9));
System.out.println("dac.isItemAtEqual(1,9)"+dac.isItemAtEqual(1,9));
}
}
Your code is fine . it is getting compiled and executed without any error on my eclipse and output is :
The list contains:4 5 6
dac.isItemAtEqual(0,9) false
dac.isItemAtEqual(1,9) false
If you convert the class to abstract, you must create a separate class that implements your abstract class.
The implementing class must override the unimplemented methods in the abstract class and can optionally override any or all of implemented methods in the abstract class
An abstract class can have a *mix of implemented and unimplemented methods. An interface class can only contain unimplemented methods.
You instantiate the class that implemenents the abstract class, but you can't instantiate the abstract class itself, because abstract classes, and interface classes are considered templates or blueprints that describe the form that the implementation must follow. It's like a recipe. You can't bake the recipe itself, you must bake the ingredients.
Working example of creating, implementing and instantiating an abstract Java class...
Shape.java: abstract class
public abstract class Shape { // Indicates this is an abstract class
protected static String shapeType = "generic shape";
abstract void draw(); // Implementing class *MUST* provide (due to 'abstract' keyword)
void logGreeting() { // Children can *optionally* override this implementation
System.out.println("I want to say hello");
}
void logDescription() { // Children can *optionally* override this implementation
System.out.println("This shape is a " + shapeType);
}
}
Circle.java: implementing class
public class Circle extends Shape { // Extends (e.g. implements) abstract class
public Circle() {
shapeType = "Circle";
}
public void logGreeting() { // Overrides implementation already in abstract class
System.out.println("This is my overridden greeting message");
}
public void draw() { // Provides implementation for *unimplemented* abstract method
// This is a NOP for example only (normally you'd put code here)
}
}
TestAbstract.java: instantiating class
public class TestAbstract extends Circle {
public static void main(String args[]) {
Circle circle = new Circle(); // instantiates implementing class
circle.logGreeting();
circle.logDescription();
circle.draw();
}
Compile the code:
javac Shape.java
javac Circle.java
javac TestAbstract.java
Execute the code:
java TestAbstract.java
Output:
This is my overridden greeting message
This shape is a Circle
Related
I have 2 subclass extended from the same superclass, and 3 objects will be created and store into an array of the superclass. I am wondering how can I call a subclass method by a superclass object, I try to convert the data type from Ship to CruiseShip or CargoShip but it does not work. If anyone can help I will be appreciated that.
Here is the superclass:
public class Ship {
private String name;
private String year;
public Ship() {}
public Ship(String n,String y) {...}
public void setName() {...}
public void setYear() {...}
public void getName() {...}
public void getYear() {...}
}
These two subclass basically are there same.
public class CruiseShip extends Ship {
private int passenger;
public CruiseShip() {}
public CruiseShip() {...}
public void setPassenager() {...}
public int getPassenager() {...}
public Strting showInfo() {this.getName()...etc}
}
public class CargoShip extends Ship {
private int capacity;
public CargoShip() {}
public CargoShip() {...}
public void setCapacity() {...}
public int getCapacity() {...}
public Strting showInfo() {this.getName()...etc}
}
Here is the main method:
public class report {
public static void main(String[] args) {
Ship[] shipList new Ship[3];
for (int i=0;i<3;i++) {//using for loop to create 3 objects randomly and pass into array}
for (int i=0;i<3;i++) {
if (shipList[i] instanceof CruiseShip) {
((CruiseShip)shipList[i]).showInfo(); //This way is not work.
}
else {
((CargoShip)shipList[i]).showInfo(); //This way is not work.
}
Take a look at Polymorphisms and Late Bindig. Basically late binding says that the appropriate method to be executed is determined at runtime based on the actual type of the object. So
class Ship {
public String showInfo() {return "I'm a ship";}
}
class CruiseShip extends Ship {
public String showInfo() {return "I'm a cruiseShip";}
}
class CargoShip extends Ship {
public String showInfo() {return "I'm a cargoShip";}
}
class Main {
public static void main(String argv[]) {
Ship[] ships = new Ship[]{new Ship(), new CargoShip(), new CruiseShip()};
for (Ship ship: ships) {
System.out.println(ship.showInfo());
// I'm a ship
// I'm a cargoShip
// I'm a cruiseShip
}
}
}
I'm not sure about the question you are trying to ask,
but this may answer the question you did ask.
public abstract class Ship
{
public final boolean hoot()
{
return implementHoot();
}
protected abstract boolean implementHoot();
}
public class BlamShip
extends Ship
{
protected boolean implementHoot()
{
return true;
}
}
Subclass methods (overrides) are automatically called even if the reference is of type super-class. You don't have to do anything.
If I add a Detective as a Book, how do I call the setPrice method (because you just can't call a child method for a parent class)?
This is the code:
public class Book {
String title;
//Contructors, get/setters, Override output methods
}
public class Detective extends Book {
int price;
//Contructors, get/setters, Override output methods
}
public class BookManager {
Book[] list;
int count = 0;
final int MAX = 100;
//Contructors, get/setters, Override output methods
public void add(Book x) {
if(count >= MAX) {
System.out.println("Failed!");
}
list[count] = x;
count++;
System.out.println("Added!");
}
public void updatePrice(String title, int newPrice) {
for(int i = 0; i < count; i++) {
if(list[i].equals(title) && list[i] instanceof Detective) {
//list[i].setPrice(newPrice) is wrong//
}
}
}
}
public static void main(String[] args) {
BookManager list = new BookManager();
Detective de = new Detective("abc", 123);
list.add(de);
//list.updatePrice("abc", 456); is wrong//
}
Is there another way to update the price?
Some options, depends how the data should be modeled.
1 - just use a cast to Detective to use its methods:
if (list[i].equals(title) && list[i] instanceof Detective) {
Detective dectective = (Detective) list[i];
detective.setPrice(newPrice);
2 - shouldn't every Book have a price?
public class Book {
String title;
//Contructors, get/setters, Override output methods
public void setPrice(int price) {
...
}
}
now it's trivial to call it:
// instanceof not need here for this to work
if (list[i].equals(title) && list[i] instanceof Detective) {
list[i].setPrice(newPrice);
eventually the method is empty in Book but overridden in Detective
public class Book {
...
public void setPrice(int price) {
// intentionally empty, overridden in aubclasses
}
}
public class Detective extends Book {
...
#Override
public void setPrice(int p) {
...
}
}
3 - one step further, assuming there is no just-a-Book, that is, only subclasses of Book: make the class and the method abstract:
public abstract class Book { // maybe make this an interface
...
public abstract void setPrince(int p);
}
and each subclass must implement that method
public class Detective extends Book {
...
#Override
public void setPrice(int p) [
...
}
}
and calling as in
if (list[i].equals(title) && list[i] instanceof Detective) {
list[i].setPrice(newPrice);
This does not allow creation of book as in new Book(...); to create a book, only subclasses are allowed, e.g. Book book = new Detective(...)
What i usually do is define an interface that the parent implements and the child can call.
Interface:
public interface IBookListener {
void updatePrice (String title, int newPrice);
}
In parent:
public class BookManager implements IBookListener {
public void add(Book x) {
x.setListener(this);
...
}
...
public void updatePrice (String title, int newPrice) {
...
}
}
In child:
public class Book {
...
private IBookListener listener;
public setLister(IBookListener listener) {
this.listener = listener;
}
public someMethod () {
listener.updatePrice("title", 1);
}
}
public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.
I got some problem with java's interfaces and abstract classes.
I have interface
public interface IVector <T extends IVector>{
public IVector add(IVector vector);
public IVector sub(IVector vector);
public double dotProduct(IVector vector);
public IVector scalar(double scalar);
}
and abstract class like this:
public abstract class Vector implements IVector{
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list){
coordinates = list;
}
public IVector add(Vector v){
ArrayList<Double> newCoordinates = new ArrayList<>();
if (v.coordinates.size() == this.coordinates.size()){
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i)+this.coordinates.get(i));
}
}
else return null;
return new IVector(newCoordinates);
}
Its just addition of vectors with n coordinates, how can i return result? I wanna use child classes (like 2dVector or 3dVector) in future?
You cannot create an abstract object directly - you need concrete class or override the required methods defined by the abstract.
Something like this may be what you are looking for.
public interface IVector<T extends IVector> {
public T add(T vector);
public T sub(T vector);
public double dotProduct(T vector);
public T scalar(double scalar);
}
public abstract class Vector<T extends Vector> implements IVector<T> {
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list) {
coordinates = list;
}
}
public class AVector extends Vector<AVector> {
public AVector(ArrayList<Double> list) {
super(list);
}
#Override
public AVector add(AVector v) {
ArrayList<Double> newCoordinates = new ArrayList<>();
if (v.coordinates.size() == this.coordinates.size()) {
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i));
}
} else return null;
return new AVector(newCoordinates);
}
#Override
public AVector sub(AVector vector) {
return null;
}
#Override
public double dotProduct(AVector vector) {
return 0;
}
#Override
public AVector scalar(double scalar) {
return null;
}
}
Note that using public abstract class Vector implements IVector in your code introduces Raw Types and should be avoided. Notice I have used public abstract class Vector<T extends Vector> implements IVector<T> instead.
To achieve your aim of making the add method generic to all Vector objects as you seem to be trying to do you need some form of factory method.
Something like this may be a fair attempt at that.
public interface IVector<T extends IVector> {
public T add(T vector);
}
public interface Factory<T> {
public T makeNew (ArrayList<Double> coordinates);
}
public abstract class Vector<T extends Vector<T> & Factory<T>> implements IVector<T> {
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list) {
coordinates = list;
}
#Override
public T add(T v) {
if (v.coordinates.size() == this.coordinates.size()) {
ArrayList<Double> newCoordinates = new ArrayList<>();
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i));
}
// Use the passed parameter as a factory.
return v.makeNew(coordinates);
}
return null;
}
}
public class AVector extends Vector<AVector> implements Factory<AVector> {
public AVector(ArrayList<Double> list) {
super(list);
}
#Override
public AVector makeNew(ArrayList<Double> coordinates) {
return new AVector(coordinates);
}
}
An abstract class cannot be instantiated: nor can an interface. You have to return either a subclass of Vector or an implementation of IVector.
I'm java virgin. I've made really simple code like below.
class TreeData implements Comparable<TreeData> {
private String sixString;
private ArrayList<Integer> stringNum = new ArrayList<Integer>();
private ArrayList<Integer> charNum = new ArrayList<Integer>();
public TreeData(String sixString, int stringNum, int charNum){
this.sixString = sixString;
(this.stringNum).add(stringNum);
(this.charNum).add(charNum);
}
public int compareTo(TreeData other) {
return sixString.compareTo(other.getSixString());
}
public String getSixString(){
return sixString;
}
}
class Child<T extends Comparable<T>>{
public void print(T data){
//error : String a = data.getSixString();
System.out.println("hi");
}
}
public class Test {
public static void main(String[] args) {
Child<TreeData> child = new Child<TreeData>();
TreeData td = new TreeData("sixString", 8, 2);
child.print(td);
}
}
I had a problem in 'print' method in the Child class. When I tried calling the getSixString() method of data(passed as argument), it occurs error. I don't know why I can't using public method in the argument 'data'. Is it related with Generic? Thanks, in advance.
In your Child class, you only define T to be extending Comparable. Yet you expect it to have the method getSixString which Comparable doesn't have. What you probably want it for it to be extending TreeData:
class Child<T extends TreeData>{
public void print(T data){
String a = data.getSixString();
//should work now since T defines getSixString()
}
}
Or better yet if all you want is for T to be TreeData, you don't need any generic class. I'm assuming your real intention was:
class Child extends TreeData {
public void print(){
String a = getSixString();
}
}