extends Spin

Download Report

Transcript extends Spin

MFA Computational Studio Arts
Programming For Artists
Inheritance
Inheritance
Note the words extends Spin attached to the
class declaration here
translate() changes the origin which
is normally 0, 0 (upper left
corner of frame)
pushMatrix() and popMatrix() are used in conjunction with the other
transformation methods and control the scope of the transformations.
We’ll look at them again in another class
/**
* Inheritance
* A class can be defined using another class as a foundation. In object-oriented
* programming terminology, one class can inherit fields and methods from another.
* An object that inherits from another is called a subclass, and the object it
* inherits from is called a superclass. A subclass extends the superclass.
*/
SpinnSpots spots; //declare a SpinnSpots object called spots
void setup()
{
size(200, 200);
smooth();
//construct spots object using word ‘new’:
spots = new SpinnSpots(width/2, height/2, -0.02, 33.0); //second to last value is speed of rotation. + or minus defines direction
//last value is diameter of ellipses
//experiment with new values try a speed of 12.0 - what happens?
}
}
void draw()
{
background(255);
spots.update(); //update() method comes from Spin class
spots.display();//display() Method comes from the subclass SpinnSpots
}
class Spin
{
float x, y, speed;
float angle = 0.0;
Spin(float xpos, float ypos, float s) { //constructor of spin
x = xpos;
y = ypos;
speed = s;
}
void update() {
angle += speed; //defines speed of rotation
}
} //.ctd>>
class SpinnSpots extends Spin
{
float dim;
SpinnSpots(float x, float y, float s, float d) {
super(x, y, s); //get x and y values from superclass, in this case Spin
//when you instantiate a spinnSpots object these values are matched to
//the fields in Spin
dim = d; //diameter of ellipse
}
void display() {
noStroke();
pushMatrix();
translate(x, y); //move origin, normally 0, 0 to user defined coordinate
angle += speed; //add speed to angle , this animates the ellipse
rotate(angle); //angle is defined in parent (or 'super') class, Spin
fill(255, 0, 0);
ellipse(-dim/2, 0, dim, dim);
//-dim/2 = -16.5, this offsets the red ellipse from the blue ellipse
fill(0, 0, 255);
ellipse(dim/2, 0, dim, dim);
popMatrix();
}
}
class SpinnSpots extends Spin
This line of code, the class declaration, is giving our class a name,
SpinnSpots and also saying that It is going to be the child or
subclass of another class called Spin
In this way SpinSpots inherits all the methods and variables in its parent
class, Spin.*
So extends Spin is like saying
“make this class the subclass of another class called Spin”
We would need to have a class called Spin that the
compiler knows about otherwise it would complain with an error message.
Here we have already created a class called Spin so that’s ok.
*If any of the methods or variables in the superclass have the word ‘private’
In front of them they will be not be directly useable by the inheriting class
We will see an example of this today.
Superclass = Bicycle
All these classes extend Bicycle
They are all subclasses of bicycle.
But each class will add its own unique features in addition to the
things it has inherited from Bicycle.
Inheritance:
A class can be defined using another class as a foundation.
In object-oriented programming terminology, one class can
inherit fields and methods from another.
An object that inherits from another is called a subclass, and the object it
inherits from is called a superclass. A subclass extends the superclass.
So in our example Spin is the superclass and SpinnSpots is the subclass
Back to Bicycles…
Different kinds of objects often have a certain amount in common with each other. Mountain
bikes, road bikes, and tandem bikes, for example, all share the characteristics of bicycles
(current speed, current gear etc). Yet each also defines additional features that make them
different: tandem bicycles have two seats and two sets of handlebars; road bikes have drop
handlebars; some mountain bikes have higher seats or tougher wheels...
Object-oriented programming allows classes to inherit commonly used state and behavior from
other classes. In this example, Bicycle now becomes the superclass of MountainBike,
RoadBike, and TandemBike. In the Java and Processing programming languages, each class
is allowed to have one direct superclass, that means they can only use extends for one class
Abstract classes and interfaces are used to get round the limitation of one extension per class. But we wont
worry about them today
So what is the benefit of inheritance and how can we use it?
The syntax for creating a subclass is simple. At the beginning of your class
declaration, use the extends keyword, followed by the name of the class to inherit
from:
class MountainBike extends Bicycle {
// new fields and methods defining a mountain bike would go here
//this is exactly the same in Java and Processing
}
This gives MountainBike all the same fields and methods as Bicycle, yet allows its
code to focus exclusively on the features that make it unique. This makes code for
your subclasses easy to read. However, you must take care to properly document
the state and behaviour that each superclass defines, since that code will not
appear in the source file of each subclass
public class little_Bike extends big_Bike
{
public static void main(String[]args)
{
System.out.println("Hello from the little_Bike class, I’ve got really small wheels");
bigHello();
//Extension allows us to call methods from the superclass as
//if we were in the superclass
Really easy to call a
method from
our superclass
}
}
public class big_Bike
{
public static void bigHello()
{
System.out.println("Hello from the big_Bike class, I’ve got big wheels");
}
}
So extension or inheritance gives us easy access to
the methods belonging to the class we are
extending
The Mystery of
POLYMORPHISM:
Last week we looked at overloading methods, that meant giving the same methods different parameters.
Overriding Polymorphism is a similar idea, except that it means that instead of just giving different parameters to
methods you can use the same method but modify what It does in the subclass, ‘Head First Java’ describes it like
this:
‘If a Dog is commanded to speak(), this may elicit a Bark. However, if a Pig is commanded to speak(), this
may elicit an Oink. They both inherit speak() from Animal, but their derived class methods override the
methods of the parent class; this is Overriding Polymorphism. ‘
Now we will do some polymorphic method
Overriding in Java
Whoopeeeee!
Remember its not the same as method overloading, this is far
more radical.
To override a method from the superclass that is a public
method, the method in the subclass also has to be public,
this just means it has to have the access modifier ‘public’
In front of it like this:
public static void bigHello()
or this:
public void bigHello()
or:
public String bigHello()
public class big_Bike2
{
public static void main(String[]args)
{
System.out.println("I'm the superclass round here");
bigHello2();
privateHello2();
//littleHello2(); //invisible to superclass, try to run it
}
public static void bigHello2()
{
System.out.println("Hello from the big_Bike2 class, bigHello2() method this is one of my big2 methods");
}
private static void privateHello2() //static but private, no object instance needed, but we cant override it
{
System.out.println("This is a private method of the big_bike2 class");
}
}
public class little_Bike2 extends big_Bike2
{
public static void main(String[]args)
{
System.out.println("Hello from the little_Bike2 class, I’ve got really small wheels");
bigHello2(); //call inherited method
littleHello2(); //call our specialised method for this class
//Extension makes it really easy to use a method from the superclass,
//unless its private!Try and call this:
//privateHello2(); //WE CANT EVEN SEE THIS METHOD from within other classes!! Uncomment it and try
}
public static void littleHello2()
{
System.out.println("Im another method in the little_bike2 class");
}
}
public class tiny_Bike extends little_Bike2
{
public static void main(String[]args)
{
System.out.println("Hello from the tiny_Bike class");
bigHello2();
littleHello2();
}
/// public static void bigHello2() // uncomment and we will override this method polymorphically!
{
System.out.println("Tiny is in control now, this is a tiny hello, hahaha");
}
}
If there are multiple implementations of a method in the inheritance
hierarchy of an object, the most derived one (the lowest in the hierarchy)
will override the others if you call it from that class. As in our
tiny_Bike2 example, when you call bigHello2() its own version
Its – overriding version is the one you get, not the one from the superclass
In BlueJ create these two classes:
public class Animal {
public static void testClassMethod() {
System.out.println("The class method in Animal.");
public class Cat extends Animal {
}
public static void testClassMethod() {
System.out.println("The class method in Cat.");
public void testInstanceMethod() {
}
System.out.println("The instance method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat.");
}
}
public static void main(String[] args) {
Cat myCat = new Cat();//ok so myCat is a subclass //object.
Animal myAnimal = myCat; //clever bit, referencing a //subclass object
//using a reference declared as the supertype
Animal.testClassMethod(); //class method of Animal I.e a static method
//addressed directly through class
myAnimal.testInstanceMethod(); //gets its instance method from Cat as it is
//an instance of a Cat object
What is the Output in the console window?
// myAnimal.testClassMethod();// try. it still gets its class method from its
//supertype because its static it is independent of an instance, it goes straight to
//its class which is Animal
//now try these:
// myCat.testInstanceMethod(); // a Cat instance method, I.e not ‘static’
// testClassMethod(); // a Cat class method, don’t need an instance to call //it
as it is static
}
}
The Cat class overrides the instance method in Animal and hides the class
method in Animal. The main method in this class creates an instance of
Cat and calls testClassMethod() on the class and testInstanceMethod() on
the instance.
So what does super mean? As its name implies
super relates to the superclass
But before we look closely into the word super
we need to look
at something called a constructor
A constructor is a neat place to initialise object variables.
It is also the place that the compiler looks to when we
use the word new
Bicycle bike1 = new Bicycle();
Behind the scenes the compiler will look through our
code to try and find a constructor, in the absence of one
there is a danger it will give our instance variables
default values, such as null or false.
A constructor helps to keep the declarations and
assignments separate and is considered to be a good
programming style.
A constructor is easy to spot, it looks very much like a
method but always has the same name as the class it is
working for:
class Car {
String color,
int speed;
public Car() {
}
}
variables waiting to be
Instantiated through an
object instance
This is the empty constructor
for a class called Car, we’d initialise
those instance or object variables in here
As in the following example:
Constructor for Car class
class Car
{
String color, body;
int doors;
Compile and run these two classes in Java
change the value of the variables in the Car
constructor and run it again, do you see how
the constructor works?
boolean goodsVehicle;
public Car()
{
public class Construct
color = "Silver";
{
body = "Sports";
public static void main (String[] args)
doors = 2;
{
goodsVehicle = false;
Car Boxster = new Car();
}
//Boxster.color = “green";
}
System.out.print("Boxster is "+Boxster.color);
System.out.print(" " +Boxster.body);
If we want to customize our objects we
can still change these values
through the dot operator, as we did
With our Bicycle objects a few weeks ago:
Boxster.color = "green";
For example. The values in the constructor
are default values.
System.out.print(" "+Boxster.doors+"-door" + "goods vehicle = " +
Boxster.goodsVehicle);
}
}
Just like methods that can be overloaded, you can also supply
more than one constructor for an object,
why would that be an advantage?
Spot sp1, sp2;
void setup()
{
size(200, 200);
background(204);
smooth();
noLoop();
// Run the constructor without parameters
sp1 = new Spot();
// Run the constructor with three parameters
sp2 = new Spot(122, 100, 40);
}
Values I assigned
Through second constructor
void draw() {
sp1.display();
sp2.display();
Default value
}
class Spot {
float x, y, radius;
// First version of the Spot constructor;
// the fields are assigned default values
Spot() {
x = 66;
y = 100;
radius = 16;
}
// Second version of the Spot constructor;
// the fields are assigned with parameters
Spot(float xpos, float ypos, float r) {
x = xpos;
y = ypos;
radius = r;
}
void display() {
ellipse(x, y, radius*2, radius*2);
}
}
The constructor of a class is not inherited by its subclasses,
that’s one good reason to use the word super,
to refer to the constructor of the superclass.
How does the word super, tie-in with inheritance?
remember when we use the word extends we are
giving the inheriting class all the (non-private) fields,
i.e. the variables and methods from the superclass,
(but not the constructor).
So how do we know if we are referring to the values of
the superclass or, for example new values we have
given those variables in the extending classes own
constructor?
That’s where the word super comes in, if we say
super.x we mean the x variable of the super class.
If you want to use the word super in a constructor it has
to be the first word you use in the constructor…you can
see that in action on slide 34.
When the word super is used the constructor in the
superclass is where the compiler looks for the type and
value of instance variables
Here again is an example of inheritance in Processing that elaborates on the spinning balls.
Don’t get bogged down in the details of the methods but try to see
how the program works as a whole with inherited methods, and how they add new functionality.
The word polymorphism is also used to describe the diversity and specialisation that
occurs in nature and the ability of animals to change form according to their environment,
apparently that’s why the O’Reilly Java books have tigers and Ducked Billed platypusses(?)
on their covers*….
*Pointless fact number 32 in an ongoing series
SpinSpots spots;
SpinArm arm;
void setup()
{
size(200, 200);
smooth();
arm = new SpinArm(width/2, height/2, 0.01); //here we have provided values
spots = new SpinSpots(width/2, height/2, -0.02, 33.0);
}
void draw()
{
background(204);
arm.update();
arm.display();
spots.update();
spots.display();
}
This is a good use of inheritance
Spin, the superclass provides the basic animating
functionality we want for both shapes –
ellipses and lines but the inheriting classes
SpinArm and SpinSpots take that functionality
And Specialise it to suit their particular shapes
This is where inheritance makes sense
class Spin
{
float x, y, speed;
float angle = 0.0;
Spin(float xpos, float ypos, float s) { //constructor for Spin, we will pass values to it when we instantiate objects
x = xpos;
y = ypos;
speed = s;
}
void update() {
angle += speed;
}
}
class SpinArm extends Spin
{
SpinArm(float x, float y, float s) { //constructor for spin arm
super(x, y, s); //reference superclass variables, ie x, y and s from Spin constructor
}
void display() {
strokeWeight(1);
stroke(0);
pushMatrix();
translate(x, y);
angle += speed;
rotate(angle);
line(0, 0, 66, 0);
popMatrix();
}
}
See next page for rest of code
class SpinSpots extends Spin
{
float dim;
//constructor for SpinSpots:
SpinSpots(float x, float y, float s, float d) {
super(x, y, s); //use x, y and s variables from Spin constructor
dim = d;
}
void display() {
noStroke();
pushMatrix();
translate(x, y);
angle += speed;
rotate(angle);
ellipse(-dim/2, 0, dim, dim);
ellipse(dim/2, 0, dim, dim);
dim is a specialised field for the
SpinSpots class because
it is using ellipses, specialisation
Is an important concept in inheritance.
It wouldn’t make much sense to have a Bike
class extending a Cat class, unless there was some
common functionality both classes needed..
Inheritance makes sense when you are building
similar objects with functions in common
– an ellipse that rotates, a line that rotates,
a bike for mountains, a bike for towns etc
popMatrix();
}
}
Inheritance gives you some common functionality
and fields while allowing you to give the new
class its own unique features.
public class thisOne
{
public static void main(String[] args) {
thatOne one = new thatOne();
one.hit();
}
public void hit()
{
System.out.println("this is a big hit from the thisOne class called by using super");
}
}
class thatOne extends thisOne {
public void hit() {
System.out.println("this is a big hit from the thatOne class, the subclass");
super.hit(); //call superclass’s hit() method
}
}
Another example of using super,
used here to refer to a method
from the superclass
Optional Lab
Have a look at the last example and try to see how inheritance
works in this program, can you add any other methods, or add
extra form to what is already a composite object? The main thing
is to understand
a) What does extends do?
b) What is the benefit of inheritance in programming?
c) Why is there a Duckbilled Platypus on the cover of some Java books?
//several overloaded methods all called oneMet()
//but with different signatures
void setup(){
oneMet();
oneMet("smoo");
print(" " + oneMet(23));
print(oneMet("Eleanor ", " sleepy "));
}
void draw(){}
///1 :
void oneMet(){
print(" hello from one met ");
}
///2:
void oneMet(String a){
print("hello from one met with a string argument " + a);
}
/////3:
String oneMet(String ab, String ba){
String mmm = ab + " " + ba + " I see, interesting ";
print(" hello from oneMet() " + ab);
return mmm;
}
/////4:
int oneMet(int ab){
int abc = ab * ab;
return abc;
}
Another example of overloaded methods.
There are 4 versions here
Rotating lines
Code to rotate lines, uses pushMatrix()
And popMatrix() in conjunction with
translate()
This contains the transformation – stops it
from effecting everything, code overleaf >>
//draw lines in a rotation:
void setup(){
size(300, 300);
smooth();
}
void draw(){
background(255);
///////////////
pushMatrix();
translate(130, 150);
//stroke(255, 0, 0);
for(int i = 0;i<100;i++){ //i defines number of lines
spin(1, 1, 10, 0);
//spin(100, 100, 10, 10);
}
popMatrix();
////////////////
//////next one:
pushMatrix();
translate(40, 150);
stroke(0);
for(int i = 0;i<100;i++){
spin(10, 10, 10, 10);
}
popMatrix();
/////////////////
}
void spin(int a, int b, int c, int d){
rotate(PI/18); //higher number = denser lines
line(a, b, c + 10, d + 10); //experiment to make longer lines
}
Building on that relatively simple code a little bit of
animation makes it quite complex… basically I just played
with the code until I liked what it did..
//draw lines in a rotation:
int cc = 0;
void setup(){
size(500, 500);
smooth();
}
void draw(){
background(223, cc, cc);
cc +=5;
if(cc>130){
cc =5;
}
else if (cc<=0){
// c = 0;
cc +=5;
}
//print(cc + " ");
///////////////
pushMatrix();
translate(width/2, height/2);
stroke(255, 0, cc);
for(int i = 0;i<240;i++){ //i defines number of lines
fill(cc, cc, 255, cc);
ellipse(120, 120, cc/2, cc/2);
spin(1, 1, cc, 0);
stroke(0, cc, 0);
spin(100, 100, 10, 10);
}
popMatrix();
////////////////
//////next one:
pushMatrix();
translate(width/2, height/2); //170, 250
stroke(255);
for(int i = 0;i<250;i++){
spin(10, 10, 26, cc);
}
popMatrix();
/////////////////
}
void spin(int a, int b, int c, int d){
rotate(PI/c); // higher number = denser lines
line(a, b, c + 10, d + 10); //experiment
}
Remember animation almost always means declaring a variable(s) outside of
any methods so that it is only called once then changed over time by having
another value, or values incremented or decremented and added to it in draw(),
which loops: