Week 3 Resit Flashcards
Procedural Abstraction
concept in cs where details are hidden within a procedure or function, allowing users to focus on high-level operations
Can be done within:
- An expressionm
- A statement
How does Procedural Abstraction can be done ?
Can be done by means of methods that:
- Operate on parameter objects
- Return a primitive value, object, or void
What is Modularisation for data
Combining variables of primitive types that frequently occur together into a single abstraction, instead of handling them separately
How can Modularisation for data can be done?
Grouping can be accomplished by String, array, and class, but only class can introduce a new name for the type
Top-down Design
- Given one big problem, split it into smaller subproblems
- Continue until reaching trivially solvable problems -> solutions
Bottom-up Design
- Given many small solutions, combine them into bigger solutions
- Continue until reaching a solution of the main problem
Enumerations
- Special data type that consists of a set of named constants (enumerators)
- Objects of an enumeration can take any of the values of the enumerators
Operations for Enumeration T
- T.VALUE (where VALUE is possible value)
- T.values()
- v.name() (v is an object of type T)
- v.toString()
-T.valueOf(s) - returns the enumeration constant for name s - v.ordinal(s) - returns the position of an enumeration constant s within its enum declaration
-v.compareTo(w) - negative return value - the first (v) comes before second (w)
Records
Provide a concise way to declare unchangeable data-carrying classes by automatically generating standard methods such as constructors, getters, equals(), hashCode(), and toString() based on the class’s fields
Featues of Records
- Cannot change the values in a record
- Can only read
- Comes with many predefined method getterMethod()
Abstract Data Type
A high-level description of a set of operations that can be performed on a certain type of data, along with the constraints or properties that these operations must adhere to.
- It defines what the data type does, not how it does it
- ADTs hide the representation of data and implementation of operations
- They are usually abstract classes/interfaces that are implemented
Abstract Data Classes
- A method can be declared abstract, and this means that it does not have an implementation
- Any class containing abstract methods must be declared abstract
- An abstract class cannot be instantiated
- A subclass can define additional instance variables and implementations for inherited abstract methods by overriding
Public invariants in ADTs
The properties or conditions that must be true for the data type’s public methods to function correctly (kinda like robustness)
Interfaces
Interfaces define a collection of method headers with contracts
Can define constants with public static final
Can have default method implementations but still no instance variables
Somewhat like a class with abstract methods but a class can implement one or more interfaces via implements by implementing each of the methods in the interface(s)
Interfaces can be viewed as a type; its values are the values of all classes that implement the interface
Interfaces vs. Abstract Classes
- Abstract classes support single inheritance while interfaces support multiple
- Interfaces cannot have constructors while AC can
- All fields in interfaces are implicitly public, static, and final
- Interfaces cannot have instance variables
ADTs as specification
abstract classes and interfaces can both be used to hold just the specification of a class, leaving the actual implementation to the classes that extend/implement them
ADT implementation Components for values
- Data representation - defined in terms of instance variables that represent intended abstract values of the ADT
- Representation invariant - refers to the conditions to be satisfied by the instance variables in order to make sense as a representation of an abstract value
- Abstraction function - maps each representation that satisfies the rep invariant to the represented abstract value
ADT implementation Components for Operations
- Involves providing a method implementation adhering to the contract for each operation
- The pre- and postconditions of each operation must be re-interpreted in terms of the data representation, using the abstraction function
- Also, the public invariant must be honoured
Polymorphisms
The ability of objects of different classes to be treated as objects of a common base class
Primitive vs. class type variables
- A variable of a primitive type always holds a value of that exact primitive type
- A variable of a class type T can hold a null reference or a reference to an instance of class T or of any class that is a subclass of T
Liskov Substitution Principle (LSP)
Let U be a subclass of T.
Type U is called a subtype of type T when:
- In each place where an object of type T can be used, you can substitute an object of type U without affecting the correctness of the program
A subtype is not only syntactically a substitute (it compiles), but also semantically (it works).
Strategy Design Pattern
Problem:
Accommodate multiple implementations of the same method by allowing selection at runtime.
Solution:
- Put specification of method in (abstract) class or interface
- Put implementations in subclasses of specification type
- Declare variable with specification type
Assign to variable an object of an implementation type
Intent of the Singleton Design Pattern
- Ensures that not more than one instance of a class is ever created
- Provides a global point of access to this instance
Solution of the Singleton Design Pattern:
- Make the constructor of the class private to prevent clients from creating instances directly
- Create a private instance of the class
- Add a public static synchronised method getInstance() that returns an instance of the class if one has not already been created
- If a class has already been created, getInstance() returns that instance
Singleton vs. Global variable
Benefits
- Both allow easy access
- Singleton ensures at most one instance is created
Drawbacks:
- Global variables creates name space pollution - as singleton access statically
- Global variables creates uncertain intialisation order -
- Global variable no access control on variable
- Both create weakened modularity - as all modules will have depend on only one instance
- Testing is more difficult - because all test most work on the same variable
- Code reuse is hindered - because you must reuse the global variable
How to avoid dependency on globals?
Parameterizing modules and supplying actual concrete globals as arguments
Make other modules depend on an abstract interface, hence they do not depend on concrete globals
Create an interface that holds the variable that would have otherwise been global and have any class that would make use of that variable implement the interface
Template Method Pattern Motivation
- Some code fragments may resemble each other without being duplicates
- Resemblance is in overall structure, and hence parameters are not a solution
- Difference is in some steps
Temple Method Pattern Intent
Create an abstract class with a final templateMethod() that calls some other methods in it.
Make those methods abstract so that they can be edited by the classes that extend the superclass.
Alternative to Template Method Patter
- Consider each step a Strategy and apply strategy design pattern
- Introduce a template method class with constructor with parameter for each abstract step type and instance varaible for each abstract step
- Client code passes concrete steps into the class
Dependency Inversion Principle (DIP)
high-level modules should not depend on low-level modules, but both should depend on abstractions
For high-level modules write abstract classes and extend the class and @overide the method
Factory Method Design Pattern Motivation
Tackles the problem of new statements requiring constructors of a concrete class, which makes client code depend on the concrete class
Factory Method Design Pattern Intent
- TO define an interface for creating n object, but subclasses decide which class to instantiate (creating an object)
Factory Method Design Pattern how to construct
- Create two different abstract classes, one called product and one called productCreator
- Inside productCreator add two method one abstract, and one with an implementation.
- Call the former (abstract) createProduct method and the latter clientCode
- CreateProduct has no implementation as it is abstract and clientCode creates a new product object and assigns to it the ouptut of createProduct
- For each of the types of products relevent create a class that extends the product abstract class and create a class that extends the product creator class.
- For each of the classes extending the productCreator class overide the createProduct method, returning an object of the product subclass represented by the product creator subclass
Encapsulate what varies
Identify the aspects of your application that vary, and separate them from what stays the same
Generic Types Definitions
- A generic type is equivalent to a parameterized type
E.g., List where E is a formal type parameter - Are used by substituting concrete class types for the formal type parameter
E.g., List,List>
Benefits are improved readability, reusability, and robustness
Iteration can abstract:
- Type of collection
- Type of its items
- Implementation details of how to accomplish iteration
Testing cases for Iterators
- Check that every element is returned exactly once (no misses, no duplicates)
- Check that iterator works without and with multiple calls to hasNext()
Some Iterator Anti-Patterns
- Giving access to internal data representation to let the client iterate - leaks representation and client can break rep invariant
- Include operations for iteration in collection class itself, which leads to not being able to have multiple iterations active concurrently
Dynamic Structure
- A stack of call methods, where a lower method calls are added on the stack when the highest method in the stack will call them
Top-level class
class that is not defined as nested or inner class within another class, but is the primary, outermost class in a Java source file
Nested class
A class that is defined within another class
Types of nested classes
- Static member class
- Non-Static member class
- Named local class
- Anonymous class
Static member class
A class inside another class with static header
or
A class in the same file with another class but not inside it
or
A class in a different file
- If it is in the same file, it cannot be public
- Only has access to instance variables and methods of outclass if they are static
- Can refer directly to all static members of outer class without qualifying there name
Non-static member class
- Has to be in a class without static header
- Each instance of nested class is associated with the instance of the top-level class inside which it was constructed
- Creating and accessing objects of inner class is done statically
- Can access all member of the out class
- Inner class cannot contain static members or unless they are also final
Named local class
- Define within a block of code, typically within a method
- Can only access the variables of the enclosing block of code, if they are declared as final or effectively final (it is assigned once and never changed but does not have the final thing)
Unanomouse class
- Special type of local class that does not have a named identifier
- often used for one-time use
- e.g. of definition, Class class = new Class() {
///inside of class }
Limirations
- Cannot define their own constructors
Benefits of Nested Classes and Interfaces
- Logical Grouping (increased coherence)
- Encapsulation (decreased coupling)
- Improving readability and maintainability
- Simpler code
Sharing/aliasing def
which is when two distinct variables name the same object
Immutably
When the state of a T object cannot change after construction
Two Equal objects if
when they are behaviourally indistinguishable. That is, every sequence of operation (queries and commands), when applied to both objects, yields the same result.
Two objects are said to be similar when ..
observationally indistinguishable. That is, every sequence of queries only (no commands), when applied to both objects, yields the same result.
==
checks whether two object references point to the exact same memory location
.equals
checks whether the actual contents or values of objects to determine if they are equivalent
Mutable vs Immutable Objects
Mutable objects are equal when they are the same object (==), whilst immutable objects are equal when they are similar.
Immutable objects are ALSO equal if they’re similar