Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Inheritance with classes

inheritance setpreferredsize

  • Please log in to reply
7 replies to this topic

#1 guamian

guamian

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 04 October 2009 - 02:12 AM

Discription:
Class Rect extends from class FillableShape
and FillableShape extends from class Shape.
Class Shape and FillableShape are two abstract classes.


I have to define the method Constrain in the subclass (class Rect) one more time. So the method Constrain can be more specified.

The problem is that when I define the Contrain method in the class Rect, the compiler show the following text:

The field Shape.box is not visible
The field Shape.box is not visible
The field Shape.box is not visible
The field Shape.box is not visible
The field Shape.x is not visible
The field Shape.dx is not visible
..... and much more, simliar like above.

As I have learned already, the subclasses inherit all the instance variabels from the superclass.
Why it's doesn't work here?




import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
 
abstract public class Shape {
	
	private double x, y; // Postion
	private double dx, dy; // Hastighet
	private Color color;
	private Rectangle box; // "Lådan", ytan figuren kan röra sig inuti.
	
	public Shape(double x, double y, Color color)
	{
		this.x = x; this.y = y;
		this.color = color;
	}
	
	public double getX() { return x; }
	
	public double getY() { return y; }
	
	public double getDX() { return dx; }
	
	public double getDY() { return dy; }
	
	public Color getColor() { return color; }

	public Rectangle getBox() { return box; }
	
	public void setVelocity(double dx, double dy) {
		this.dx = dx; this.dy = dy;
	}
	
	/** Förflyttar figuren ett steg (dx, dy).
	 */
	public void move() {
		x += dx; y += dy;
		constrain(); // Håll figuren inom lådan, se nedan
	}
		 
	public void setBoundingBox(Rectangle box) {
		this.box = box;
	} 
	
	/** Håller figuren inom lådan
	 */
	public void constrain() {
		// Hämta lådans mått (box.x, box.y)
		double x0 = box.x, y0 = box.y;
		double x1 = x0 + box.width;
		double y1 = y0 + box.height;
		
		// Om utanför lådan - byt riktning
		if(x < x0) dx = Math.abs(dx);
		if(x > x1) dx = -Math.abs(dx);
		if(y < y0) dy = Math.abs(dy);
		if(y > y1) dy = -Math.abs(dy);
	}
	
	/** Ritar figuren, abstrakt metod
	 */
	abstract public void paint(Graphics g);
}

import java.awt.Color;

abstract public class FillableShape extends Shape
{
	private boolean filled;
	
	public FillableShape(double x, double y, Color color)
	{
		super(x, y, color);
	}
	
	public void setFilled(boolean v)
	{
		filled = v;
	}
	
	public boolean getFilled()
	{
		return filled;
	}
	
	public void constrain()
	{
		// Hämta lådans mått (box.x, box.y)
		double x0 = box.x, y0 = box.y;
		double x1 = x0 + box.width;
		double y1 = y0 + box.height;
		
		// Om utanför lådan - byt riktning
		if(x < x0) dx = Math.abs(dx);
		if(x > x1) dx = -Math.abs(dx);
		if(y < y0) dy = Math.abs(dy);
		if(y > y1) dy = -Math.abs(dy);
	}

}


import java.awt.Color;
import java.awt.Graphics;

public class Rect extends FillableShape
{
	private double x2;
	private double y2;

	public Rect(double x, double y, double x2, double y2, Color color)
	{
		super(x, y, color);
		this.x2 = x2;
		this.y2 = y2;
	}
	
	public double getX2()
	{
		return x2;
	}
	
	public double getY2()
	{
		return y2;
	}
	
	public void constrain()
	{
		// Hämta lådans mått (box.x, box.y)
		double x0 = box.x, y0 = box.y;
		double x1 = x0 + box.width - x2;
		double y1 = y0 + box.height - y2;

		// Om utanför lådan - byt riktning
		if(x < x0) dx = Math.abs(dx);
		if(x > x1) dx = -Math.abs(dx);
		if(y < y0) dy = Math.abs(dy);
		if(y > y1) dy = -Math.abs(dy);
	}
	
	public void paint(Graphics g)
	{
		/*
		if(filled == true)
		{
			g.fillOval( (int)this.getX(), (int)this.getY(), 
					(int)this.getX2(), (int)this.getY2());
		}
		*/
		g.setColor(this.getColor());
		g.drawRect( (int)this.getX(), (int)this.getY(), (int)x2, (int)y2);
	}
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;


public class BouncePanel extends JPanel implements Runnable {
	
	private int width = 400, height = 300;
	private Thread thread;
	
	// En array av referenser till ritbara objekt.
	private Shape[] shapes;
	Rectangle box = new Rectangle(width, height);
	private boolean filled;
	
	
	public BouncePanel() {
		
		// Skapa ritbara figurer och initiera dessa
		// . . .
		// . . .
		shapes = new Shape[3];
		
		// Create a new Line
		shapes[0] = new Line(0.0, 0.0, 2.0, 3.9, Color.blue);
		shapes[0].setBoundingBox(box);
		shapes[0].setVelocity(1.2, 2.5);
		
		
		// Create a new Circle
		shapes[1] = new Circle(0.0, 0.0, 10.0, Color.red);
		shapes[1].setBoundingBox(box);
		shapes[1].setVelocity(5.2, 1.5);
		
		// Create a new Rect
		shapes[2] = new Rect(0.0, 0.0, 20.0, 30.0, Color.gray);
		shapes[2].setBoundingBox(box);
		shapes[2].setVelocity(2.3, 2.6);
		
		// Sätter ritytans (BouncePanel) storlek. 
		setPreferredSize(new Dimension(width, height));
		
		// Skapar ett Thread-objekt, som exekverar metoden run som
		// en separat aktivitet, tråd.
		thread = new Thread(this);
		thread.start();
	}
	
	/** Anropas av repaint(). Definierar vad som ska ritas.
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		// Rita alla figurer
		// . . .
		// . . .

		shapes[0].paint(g);
		shapes[1].paint(g);
		shapes[2].paint(g);
	}
	
	/** Uppdaterar bollens position och ritar upp den.
	 *  Denna metod exekveras av tråden thread.
	 */
	public void run() {
		while(true) {
			// Flytta alla figurer
			// . . . .
			// . . . .
			shapes[0].move();
			shapes[1].move();
			shapes[2].move();
			
			repaint(); // Anropar paintComponent(Graphics g) 
			
			// Vila i 20 ms innan nästa uppritande
			try {
				Thread.sleep(20);
			}
			catch(InterruptedException e) {}	 
		}
	}
}


import javax.swing.*;

/** Denna klass innehåller main där ett fönster (frame) för 
 *  applikationen skapas.
 */
			
public class Bounce {
	public static void main(String[] args) {
		// Skapa ett fristående fönster för programmet.
		JFrame frame = new JFrame("Bounce");
		
		// Skapa en rityta (BouncePanel) med en boll och
		// placera denna i fönstret.
		BouncePanel panel = new BouncePanel();
		frame.getContentPane().add(panel);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}

  • 0

#2 ZekeDragon

ZekeDragon

    CC Leader

  • Retired Mod
  • PipPipPipPipPipPipPip
  • 1263 posts

Posted 04 October 2009 - 02:29 AM

You declared those fields as private. Private fields, such as "box", cannot be accessed by derived members of the class. All subclasses do inherit instance variables form super classes, however private members are still not reachable by their child classes. Observe:
private Rectangle box;
Here you declared "box" to be private. That means the shape class and ONLY the shape class can access "box". Nothing else can, not even derived classes of shape. This is a principle of encapsulation. If you want to allow derived members to access the "box" field, you'll need to declare it as protected instead. However, in my honest opinion the best method to maintain encapsulation and also allow access to the "box" field is to use what you already have available, the public method "getBox()". For example:
double x1 = x0 + getBox().width;
		double y1 = y0 + getBox().height;
That would be preferred. All you have to know is that private members of base classes cannot be accessed by derived classes.
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?

#3 wim DC

wim DC

    Roar

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 2681 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Python

Posted 04 October 2009 - 02:40 AM

Yes they are not visible because you set them as private. Makes them only visible for the class itself.
If you want them to be visible for the inherited classes aswell you should make them "protected" if you want them to be visible to any class "public" (<-- public is not recomended)

I am having troubles with the new Line and new Circle... dunno why really. if i make 3 rectangles it works like a charm.

oh Zeke you were before me :o Didn't refresh my window for a while when i was messing with the shape[0] = new Line(....) does that one work for you? same with the circle. I suppose there are more classes like the rect one.
  • 0

#4 guamian

guamian

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 04 October 2009 - 09:27 AM

Thanks! I fixed some of the problems, but i still don't know how to solve this problem. See the comment.

public void constrain()
	{
		
		// The size of the box (box.x, box.y)
		double x0 = getBox().x, y0 = getBox().y;
		double x1 = x0 + getBox().width - x2;
		double y1 = y0 + getBox().height - y2;

		// Change direction
                         // I have no idea about how to change the variabel "dx" and "dy" here
                         // Any tips/suggestions?
		if(getX() < x0) dx = Math.abs(getDX());
		if(getX() > x1) dx = -Math.abs(getDX());
		if(getY() < y0) dy = Math.abs(getDY());
		if(getY() > y1) dy = -Math.abs(getDY());
	}

  • 0

#5 Tudose

Tudose

    CC Lurker

  • Just Joined
  • Pip
  • 2 posts

Posted 05 October 2009 - 06:56 AM

The problem is that you are still trying to access a private field from within another classroom, as you previously did with the box field. As stated above, a private field cannot be accessed from another class, not even from a subclass.

The solution would be either to make the fields protected or package private (meaning they do not have any access modifier), or (recommended) to call the existing public getters and write new public setters.

So, inside the Shape class, insert this code:

public void setDX(double dx){
this.dx = dx;
}

public void setDY(double dy){
this.dy = dy;
}


Comment: this.dx and this.dy refer to the class fields, while dx and dy refer to the parameters of the methods. It is said that the class fields are shadowed by the parameters of the methods.

Inside the FillableShape class, insert this code:

if(getX() < x0) {
setDX(Math.abs(getDX()));
}

if(getX() > x1) {
setDX(-Math.abs(getDX()));
}

if(getY() < y0) {
setDY(Math.abs(getDY()));
}

if(getY() > y1) {
setDY(-Math.abs(getDY()));
}


  • 0

#6 guamian

guamian

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 06 October 2009 - 03:04 AM

Thank you very much for the explainations.

I modified the program as what you said.
There is no errors in the program, but doesn't work as expected.
The ball (Circle) bounces really really strange. It doesn't bounce back when hit the bottom.

I understand the codes, but this makes me totally confused....
  • 0

#7 Tudose

Tudose

    CC Lurker

  • Just Joined
  • Pip
  • 2 posts

Posted 06 October 2009 - 03:19 AM

This is something that you should debug. I am not aware of what you are expecting from the program, so you are the one that should run and debug it.
I assume that the Shape and FillableShape classes work fine now, so you should look for the error in the other classes.
  • 0

#8 GMVResources

GMVResources

    CC Resident

  • Just Joined
  • PipPipPipPip
  • 71 posts

Posted 13 June 2010 - 05:46 PM

Yea you dont need to debug though, all you need to know is that it is you can't inherit from private classes it's only public,
  • 0





Also tagged with one or more of these keywords: inheritance, setpreferredsize