Unit 5 Writing Classes
Homework for Unit 5: Writing Classes
Notes
What I learned
Static methods are used mainly for convenience. If you create a regular method, you need to create an object to execute the method. However, an object does not need to be created to access a static method.
Polymorphism: This is used with Java extends
. When a method in the subclass has the same name as the superclass, the subclass's method will override the superclass's.
Late binding results in overriding, or using the specific subclass's method during run time. On the other hand, if two methods have the same name but different parameters, using one method over the other would be called overloading.
private
vs protected
: Private only allows access within the class, while protected allows access in the same package or subclasses.
Below is a piece of code that illustrates many parts of a class.
public class Person {
private int age;
private int height;
public Person(){
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return this.height;
}
public void setHeight(int height) {
this.height = height;
}
public static void main(String[] args) {
Person person1 = new Person();
person1.setAge(20);
person1.setHeight(65);
System.out.println("person1's age is: " + person1.getAge());
System.out.println("person1's height is: " + person1.getHeight());
}
}
Person.main(null)
Explanation of items in the code
A class is like a blueprint for an object. In this case, the class is Person
(names of classes by convention have the first letter capitalized). The Person
class has an empty constructor. Common things found in a class are getters and setters. Getters are created with getvariable name
, and setters are created with setvariable name
. In both cases, the first letter of the variable name should be capitalized, as in accordance with Java variable naming conventions. Getters and setters are used to protect your data so that you do not assign unintended values to your variables. Lastly, the this
keyword is used to refer to the declared variables. this
is used to differentiate between the declared variables and the variables that are passed into a method as parameters and who may have the same name.
public class Access{
public int x = 5;
}
public class AccessTwo {
public static void main(String[] args) {
Access variableDemo = new Access();
System.out.println(variableDemo.x);
}
}
AccessTwo.main(null)
Compare with this:
public class Access{
private int x = 5; // x is private
}
public class AccessTwo {
public static void main(String[] args) {
Access variableDemo = new Access();
System.out.println(variableDemo.x);
}
}
AccessTwo.main(null)
On the other hand, protected allows access only in the same package and subclasses.
public class Access{
protected int x = 5; // x is private
}
public class AccessTwo extends Access {
public static void main(String[] args) {
AccessTwo variableDemo = new AccessTwo();
System.out.println(variableDemo.x);
}
}
AccessTwo.main(null)
public class staticDemo{
static int staticVar = 5;
public static void main(String[] args) {
System.out.println(staticVar);
}
}
staticDemo.main(null)
This will produce an error because there is no static!
public class staticDemo{
int staticVar = 5;
public static void main(String[] args) {
System.out.println(staticVar);
}
}
staticDemo.main(null)
Static variables can be accessed in nonstatic methods!
public class staticDemo{
static int staticVar = 5;
public void printVar() {
System.out.println(staticVar);
}
public static void main(String[] args) {
staticDemo a = new staticDemo();
a.printVar();
}
}
staticDemo.main(null)
public class Cat{
public boolean hasTail() {
return true;
}
public void sayMeow() {
System.out.println("Meow!");
}
}
public class TabbyCat extends Cat {
public String furType() {
return "striped";
}
public boolean hasTail() {
return super.hasTail();
}
public static void main (String[] args) {
TabbyCat cat1 = new TabbyCat();
cat1.sayMeow();
System.out.println("Tabby cat fur type: " + cat1.furType());
System.out.println("Tabby cat has tail? " + cat1.hasTail());
}
}
TabbyCat.main(null)
In the example above, the superclass is Cat
, while the subclass is TabbyCat
. Extends helps save time from copying and pasting code. TabbyCat
has access to all of the methods in Cat
, but also has its specific method, furType()
. The super
keyword calls the superclass.
One interesting thing is that if the subclass has the same method as the superclass, the subclass's method will override the superclass. This is called polymorphism. See below:
public class TabbyCat extends Cat {
public String furType() {
return "striped";
}
public boolean hasTail() {
return false; // oof
}
public static void main (String[] args) {
TabbyCat cat1 = new TabbyCat();
System.out.println("Tabby cat has tail? " + cat1.hasTail());
}
}
TabbyCat.main(null)
During compilation though, the hasTail()
method will be looked for in the Cat
class. Only during run time, the method will be resolved to the TabbyCat
object. This is called late binding (using overriding)
Something very cool in Java is that you can have methods with the same name, as long as they have different parameters. This would result in overloading.
abstract class AbstractCat {
public void sayMeow() {
System.out.println("meow");
}
}
class TabbyCatAbstract extends AbstractCat{
public String furType() {
return "striped";
}
public static void main(String[] args) {
TabbyCatAbstract tabbycat = new TabbyCatAbstract();
System.out.println(tabbycat.furType());
}
}
TabbyCatAbstract.main(null)
Integer x = 5;
System.out.println("Data type of x is: " + x.toString().getClass().getSimpleName());
String text = new String("foo");
String text2 = new String("foo");
if (text.equals(text2)) {
System.out.println(text.hashCode() == text2.hashCode());
}
Big O notation
Big O provides the worst case time complexity of an algorithm. It is written in the format of O(n), where n is the size of the input. The worst case time complexity is taken in that say if the function was 2n+3, you would write it as O(n) because as n increases, the 3 becomes less important.
The Big O notation for hash maps is O(1), which is the fastest possible running time. Binary search is O(logn). A single loop is O(n), while a nested loop is O(n^2).
public class StepTracker {
private int numDay;
private int activeSteps;
private int totalSteps;
private int numActiveDays;
public StepTracker(int steps) {
activeSteps = steps;
}
public int activeDays() {
return numActiveDays;
}
public double averageSteps() {
return totalSteps/numDay;
}
public void addDailySteps(int steps) {
totalSteps += steps;
numDay++;
if (steps >= activeSteps) {
numActiveDays++;
}
}
}
Comments:
In the method averageSteps()
, I did not do a type conversion to double in my return statement. A type conversion is needed because totalSteps
and numDay
are integers.
I also did not account for when numDay
= 0, because the return statement can not be divided by 0. Therefore, an if statement is needed to return an average step of 0.
Corrections:
public class StepTracker {
private int numDay;
private int activeSteps;
private int totalSteps;
private int numActiveDays;
public StepTracker(int steps) {
activeSteps = steps;
}
public int activeDays() {
return numActiveDays;
}
public double averageSteps() {
if (numDay == 0) { // corrections
return 0.0;
} else {
return (double) totalSteps/numDay;
}
}
public void addDailySteps(int steps) {
totalSteps += steps;
numDay++;
if (steps >= activeSteps) {
numActiveDays++;
}
}
}