structuring-models
Download
Report
Transcript structuring-models
Structuring Models
CS1316: Representing
Structure and Behavior
Story
Exploring classes, superclasses/subclasses,
constructors, Strings, and println
Let’s make a Person
Let’s make a Student a kind-of Person
Setting them new objects automatically
How inheritance works, and how overriding
works
• People have names
• Students have ID numbers.
People have names
public class Person {
public String name;
}
> Person fred = new Person();
> fred.name
null
> fred.name = "Fred";
> fred.name
"Fred"
Should we be able to rename
Fred?
> fred.name = "Mabel";
> fred.name
"Mabel"
This is the what public
instance variables
(sometimes called
fields) allow us to do?
If we wanted to control names,
can do it in accessors
> Person fred = new Person();
> fred.setName("Fred");
> fred.getName()
"Fred"
public class Person {
private String name;
Could check in
setName(): “Are you
allowed to change my
name?”
Could check in
getName(): “Are you
allowed to ask my
name?”
public void setName(String somename)
{this.name = somename;}
public String getName()
{return this.name;}
}
Barney may not be bright,
but is he really null?
> Person barney = new Person();
> barney.getName()
null
How could we set up a person’s
name right from the start?
Making new people have
reasonable names
public class Person {
private String name;
public Person(){
this.setName("Not-yet-named");
}
public void setName(String somename)
{this.name = somename;}
public String getName()
{return this.name;}
}
> Person barney = new
Person()
> barney.getName()
"Not-yet-named"
The Constructor
A method with the same name as
the class.
It’s called when a new instance of
the class is created.
public Person(){
this.setName("Not-yet-named");
}
Constructors can take inputs
(arguments)
public class Person {
private String name;
public Person(){
this.setName("Not-yet-named");
}
public Person(String name){
this.setName(name);
}
public void setName(String
somename)
{this.name = somename;}
public String getName()
{return this.name;}
}
> Person barney = new
Person("Barney")
> barney.getName()
"Barney"
> Person wilma = new Person()
> wilma.getName()
"Not-yet-named"
> wilma.setName("Wilma")
> wilma.getName()
"Wilma"
Both constructors exist. Java
uses the right one depending on
the arguments provided.
Must match inputs to some
constructor
> Person agent99 = new Person(99)
java.lang.NoSuchMethodException: Person constructor
There are constructors for no inputs
and String inputs, but not for double
or int inputs.
Some discourse rules for Java
In a Western, the hero carries a gun, never a bazooka
and never flies on a unicorn.
•
There are “discourse rules” in different genres.
There are such rules in Java.
•
•
•
•
•
Class names start with capital letters.
They are never plurals. (Want more than one of them?
Make an array or a list!)
Instance variables and methods always start with lowercase
letters.
Methods should describe verbs—what objects know how to
do.
Accessors are typically set- and get- the name of the field.
But what is Barney?
> Person barney = new Person("Barney")
> barney
Person@63a721
Looks like “Person” then
cuss word…
Making the printable
representation of People better
public class Person {
private String name;
public String toString(){
return "Person named "+this.name;
toString() is called
}
> Person barney = new Person("Barney")
> barney
Person named Barney
whenever an object
needs to be converted
to a string—such as
when it is printed in the
Interactions Pane
Students are people, too.
Let’s make Students
• They are Persons
• But they also have ID#s
• (Not exactly the best model in the world. Real
students also have homes, friends, etc. But
you only model what you need, and right now,
we just need another data element.)
Students are kind-of Persons
• Students extend Persons
Making Students
public class Student extends Person {
private int idnum;
public int getID(){ return idnum;}
public void setID(int id) {idnum = id;}
}
Making Betsy
> Student betsy=new Student("Betsy")
java.lang.NoSuchMethodException: Student constructor
> Student betsy = new Student()
> betsy.getName()
Can’t make Betsy by name,
"Not-yet-named"
because that only exists for
> betsy.setName("Betsy")
Persons so far.
> betsy.getName()
Betsy does inherit the existing
constructor for no input.
"Betsy"
> betsy.setID(999)
Betsy does inherit setName and
> betsy.getID()
getName.
999
And Betsy now has getID and
setID
Who is Betsy?
> betsy
Person named Betsy
Students inherit
the toString() of
the parent class.
Setting up Student constructors
public class Student extends Person {
private int idnum;
// Constructors
public Student(){
super(); //Call the parent's constructor
idnum = -1;
}
public Student(String name){
super(name);
idnum = -1;
}
public int getID(){ return idnum;}
public void setID(int id) {idnum = id;}
}
If a Student has no ID,
the default now is -1.
If we want to call the
parent’s constructor, we
must do it in the FIRST
line.
Your turn:
Actually try these in class
Make a new constructor for Student that
takes a name and an ID, so that we can
say:
Student mark = new Student(“Mark”,29)
Make a toString() for Students so that
they respond with name and ID.
Can we have a main() here?
Any class can have a public static
void main(String[] args)
method.
What would you use it for?
How about for testing?
• Use it like we use the Interactions Pane
Getting values printed out
How do we get things printed to the
Interactions Pane from inside a main()?
System.out.println(“Some
String”)
A main() for Persons
public static void main(String [] args){
Person fred = new Person("Fred");
Person barney = new
Person("Barney");
System.out.println("Fred is "+fred);
System.out.println("Barney is
"+barney);
As long as you start
with a string, you
can “add” (with “+”)
any object and it
will be made into a
string.
}
Welcome to DrJava.
> java Person
Fred is Person named Fred
Barney is Person named Barney
public class Person {
private String name;
The whole
Person.java
public Person(){
this.setName("Not-yet-named");
}
public Person(String name){
this.setName(name);
}
public String toString(){
return "Person named "+this.name;
}
public void setName(String somename)
{this.name = somename;}
public String getName()
{return this.name;}
public static void main(String [] args){
Person fred = new Person("Fred");
Person barney = new Person("Barney");
System.out.println("Fred is "+fred);
System.out.println("Barney is "+barney);
}
}
Exploring greetings
A subclass inherits all structure (data)
and behavior (methods) from superclass.
Unless it overrides it.
A new method for Person
public void greet(){
System.out.println("Hi! I am "+this.name);
}
> Person bruce = new Person("Bruce")
> bruce.greet()
Hi! I am Bruce
> Person george = new Person("George W.")
> george.greet()
Hi! I am George W.
> Student krista = new Student("Krista")
> krista.greet()
Hi! I am Krista
Should
students
greet() in the
same way?
Trying to give Student a greet()
This way works
public void greet(){
System.out.println("Hi, I'm
"+this.getName()+
", but I got to run to class...");
}
Changes Student, but not
Person
Welcome to DrJava.
> Person george = new Person("George W.")
> george.greet()
Hi! I am George W.
> Student krista = new Student("Krista")
> krista.greet()
Hi, I'm Krista, but I got to run to class...
Think about what happens here
When we tell krista to greet()
•
•
•
“I am a Student. Do I know how to
greet()? If I don’t, I’ll ask my
parent, Person, to handle it.”
“I do know how to greet()! I’ll
execute that method!”
“Uh-oh. I don’t know how to
getName(). Oh, Parent?!? Can
you handle getName()?”
public void greet(){
System.out.println("Hi,
I'm "+this.getName()+
", but I got to run to
class...");
}
Declaring the variable from the
superclass
Why does the first person work, but the second
one doesn’t?
Think of the variable as a box with a label on it.
•
•
“fred is a box that can contain Persons. A Student is a
kind of Person, so that fits.”
“mabel is a box that can contain Students. Any old
Person is not a Student!”
Accessing methods through
these “boxes” (variables)
> Person fred = new Student("Fred")
> Student mabel = new Person("Mabel")
Error: Bad types in assignment
> fred.greet()
Hi, I'm Fred, but I got to run to class...
> fred.setID(999)
Error: No ‘setID' method in 'Person'
> ((Student) fred).setID(999)
> ((Student) fred).getID()
999
We get the right
greet() because fred
is a Student.
But because fred is a
Person, we can’t
immediately get to
Student-only
methods.
We have to convince
Java what kind of
thing it is by casting.