CSC207 Notes
Lecture Notes
Click to show lecture material
## Object oriented programming ### Features - Abstraction: the essential characteristics of something - Encapsulation: - putting data together with methods to manipulate it - hiding how it all works behind the schenes - Inheritance: subclasses getting features of another class - Polymorphism: - an expression can take on different things - e.g. method calls that have different types as an inputs ### Coupling and cohesion - coupling: how closely two classes are linked - high coupling: changes to one class means a lot of changes in other classes - low coupling: changes to one class shouldn't affect others too much (this is preferred!) - cohesion: how closely related features of a class are - high cohesion: methods are strongly-related (this is preferred!) - low cohesion: methods are not that related and don't seem to make that much sense as a package together ### Design principles - techniques for making programs easy to read, **hard to break**, maintainable, and efficient (for people) ### SOLID design: - **S**ingle reponsibility principle: A class should have one, and only one, reason to change - **O**pen/closed principle: Classes should be open for extension but closed for modification - **L**iskov substitution principle: Subclasses should add to a base class’s behaviour, not replace it - **I**nterface segregation principle: Many client-specific interfaces are better than one general-purpose interface - **D**ependency inversion principle: - high-level code shouldn’t depend on low-level code, both should depend on abstractions - abstractions shouldn’t depend on details, details depend on abstractions
PCRS Quest 1
Click to show Quest 1 material
## Hello World - no code exists outside a class - there are no functions, but methods exists public static void main(String[] args){} - when a class is run, this method is automatically called - public declares what has access to that object ```java System.out.println(5+7); ``` - System is the class - out is a static member in the class - println is a method within that member - 5+7 is the expression ## Variables ```java int i; //default value for int is 0 Object obj; //default value for any object is null String name = "CSC207"; //note the capital 'S' and double quotes boolean isTrue = false; //lowercase boolean values (true/false) double gpa = 0.0; ``` ## Errors: ```java number = 42; //didn't declare variable int i = 19.22; //type mismatch: can't convert double to int int i = 1; int i = 2; //duplicate local variable ``` ## References vs Primitives - Java has **primitive** and **reference** types - primitive types directly hold values, while reference types point to values - primitive types start with lower case letters (int, boolean, etc) - reference types start with upper case letters (String, etc) can call using String s1 = new String("..."); - call stack keeps track of what method we're running - object space is where objects are stored - static space is where static members of a class are stored - string variables from the call stack get an id referencing the String object in the object space ## Strings pt 1 - Strings are immutable (can't ever change a String variable once created, but can perform operations on it) ```java String s3 = s2 + s1; //add two strings to make a new one char c = s1.charAt(2); //get the character at index 2 s1 = s1.substring(2, 4); //slice a string (like s1[2:4]) s1 = " I am a string . "; s1 = s1.trim(); //get rid of extra spaces ``` - other methods: length, startsWith, indexOf, etc... - for mutable strings: ```java StringBuilder sb = new StringBuilder("hi"); sb.append(" world."); //now contains "hi world." sb.insert(2, " there"); //now contains "hi there world." sb.setCharAt(14, '!'); //now contains "hi there world!" //(note single quotes for char) sb.reverse() ``` - adding Strings can be slow because it creates a whole new string each time - appending to StringBuilders is faster because it modifies an existing one ## Strings pt 2 ```java String a = new String("abcd"); String b = new String("abcd"); System.out.print(a == b); //prints false because a and b have been declared as 'new' ------------ String a = "abcd"; String b = "abcd"; System.out.print(a == b); //prints true because Java tries to reuse string locations // and sets 'b' to point to same spot as 'a' ------------ //all of these are valid initializations String a = "hello"; String a = new String("hello"); String a; a = new String("hello"); String a; a = "hello"; ------------ String a = "hi"; a = "hello"; //NOT valid ``` ## Classes ```java int i = ___; String val = String.valueOf(i); //turns an int to a string System.out.println(Integer.BYTES); //prints the number of bytes of an integer ``` - automatic de-allocation when variable doesn't refer to anything, don't need to free anything - can explicitly de-allocate by setting a variable to null ## Arrays - array length can't be changed - all elements must be of the same type - arrays are reference types, not primitive types ```java //an array of ints, nums is a variable that refers to the array int[] nums; /all indices contain default value, 0 nums = new int[5]; int[] nums = {1,2,7,109,888}; //array holds {1,2,7,109,888} nums[1] = 81; //array holds {1,81,7,109,888} ``` - no negative indices, no slicing - add different types into same array: ```java Object[] rand = new Object[5]; rand[0] = new String("hello"); rand[1] = new Integer(1000); rand[2] = new Monster("Fred"); //array inside an array rand[3] = new int[50]; //add the first element into another variable Object element = rand[0]; //DOESN'T WORK, even if rand[0] is a string String element = rand[0]; //works if rand[0] can be typecast to a string String element = (String)rand[0]; int[][] table; // 2D array ``` ## Alias - can only create an alias with a MUTABLE reference type (primitives don't create objects) - If object is immutable (e.g. strings), changing string creates a copy - if alias object changes, original still points to it - careful with double & farther aliases (e.g. array of array of strings) - primitive types are compared by VALUES and class types are compared by REFERENCES ## Control Structures ```java if (variable > 500){ doStuff(); } else if (variable > 400) { doOtherStuff(); } else { doMoreStuff(); } if (variable > 500) doStuff(); //good for one line inside only while (variable > 500){ variable -= 1; } for (initialization; termination; increment){ //do stuff here } for (Object item : listOfItems){ //do stuff } do { //makes sure loop will run at least once //stuff } while (condition); //note semicolon ``` ## While loops ```java i++; //checks value, then increments ++i; //increments, then checks value while(array[i++] < 7) //... ``` ## Classes - two types of variables declared outside method: instance and class variables - instance vars: come into existance when a new object of that class is constructed - class vars: shared by all instances of a class (denoted by saying 'static') - constraints (for values, relationships, etc) should be recorded - MUST hold true before (assumed) and after (check!) a method runs - constructors have same name as class and are called automatically - NO return type (not even void) - can overload constructors (to make multiple!) - to call other constructors, call 'this(arguments_here)' - if NO constructors are supplied, Java makes a no-arg default constructors - better to make 'getter' and 'setter' methods than to make variable public - this allows the API to change, but the user to use it the same - use '@Override' then method itself to recreate a method ```java @Override //overrides original toString method, and allows tweaking of it public String toString(){ //... } //SHOULD ALSO OVERRIDE HASHCODE (didn't in this case) @Override //redefines what equals means for this class public boolean equals(Object obj){ //test if 'this' is the same as 'obj' by some method } ``` ## Parameters - when a method is called: - new stack frame is added to stack - parameters are defined on the stack frame - value in each argument is assigned to its parameter - parameters vs arguments: - each variable in a method definition is a parameter - each variable in a method call is an argument - each argument passed to a method tries to create an alias - for primitives, just copies value, for reference, it mutates values
PCRS Quest 2
Click to show Quest 2 material
## Overloading
- two methods that have the same name but different parameters
- one can be a default, and the other can call it, or they can process inputs differently, etc
- must be inside the same class
- interfaces are clearer to work with
## Static
- means you can have (for example) one variable that each instance of a class shares
- make good counters, etc
- kind of like global variables, but better
- static variables can be inside any methods
- regular variables CANNOT be inside static methods
## toString and equals
- toString has an default method already created for each object
- can create your own toString method that overrides default
- all object types have a toString method
- equals has a default method already created for each object
- like toString, can override default
- hashmaps can map an object to a list
## Equality (== vs. equals) pt 1
- '==' checks if references are the same
- 'equals' checks if the content is the same
- every class has an equals method (defaulted to checking identities if you didn't declare it)
- **string interning** is where Java saves space by using only one object for each distinct string
- calling 'new' creates a new version of that string
- Something to think about: If declaring two new strings, and then a third not-new one, which one is reused?
```java
String s1 = "ice cream";
String s2 = "ice" + " " + "cream";
System.out.println(s1 == s2); //prints true
```
## Comparator and Comparable
- can use '.sort' on any array of comparable types
```java
public static void sort(Object[] a){} //the sort method (default)
----------
//to let sort do its job, need to implement the below:
//to have comparability, must also have the class implement:
class ClassName implements Comparable