Data Structures Chapters 1-3
What is an interface?
An interface is an abstract class that contains nothing but abstract methods It is declared with the keyword interface (instead of class or abstract class) It does not contain fields or constructors Since all methods are public and abstract, there is no need to include those keywords in their declaration. Interfaces, like abstract classes, can be used to declare objects but NOT to instantiate them
Type hierarchy (explain in the context of Student and gradStudent)
Classes allow us to define our data types. Student and GradStudent are data types. More specifically, GradStudent is a subtype of Student, and Student is the base type of GradStudent Since inheritance is transitive, it allows us to create a hierarchy of types
What is a data type?
Classes allow us to define our own data types. A data type consists of a type (a collection of values) together with a collection of operations to manipulate the type ex: an integer variable is a member of the integer data type. Integer arithmetic is an example of operations allowed on the integer data type. Boolean arithmetic is an example of operations not allowed on the integer data type
How to create a custom exception
Creating custom exceptions can be as simple as extending an existing built-in exception Alliteration: extends exceptionName ex: make own version of IndexedOutOfBoundsException called IndexException - create a class IndexException that extends RuntimeException public class IndexException extends RuntimeException { } - update IndexedList, IndexedListTest, and ArrayIndexedList: replace any usage of IndexOutOfBoundsException with IndexException All built-in exceptions have a default constructor and an overloaded constructor that takes a String (message) as a parameter. It is good practice to provide a similar overloaded constructor for your custom exceptions
What is inheritance?
Inheritance is a mechanism that allows classes to be derived from other classes, with the child classes inheriting fields and methods from the parent class In addition to the properties inherited from the super-class, the sub-class can define its fields and methods Inheritance is a one-way relationship. Therefore, the parent class does not have access to the (additional) attributes/methods declared in a child class
Method overloading
Overloading is having two methods with the same name but different types or number of parameters (or both)
What is abstraction? Explain it in the context of the student class
Student is an abstraction; there is so much information we could capture to represent (model) a student, but we only store what matters to us (the problem we are trying to solve). In this case, the information of interest are name and email
What is multi-level ineritance?
The chain of inheritance relations (where a sub-class is inherited from another sub-class). Inheritance is transitive.
Update the declaration of IndexedList.get to make it robust
/** * Retrieve the value stored at the given index. * * @param index representing a position in this list. * @return value at the given index * @throws IndexOutOfBoundsException when index < 0 or index >= length. */ T get(int index) throws IndexOutOfBoundsException; (*note that we removed the pre-condition. Instead, the method throws IndexOutOfBoundsException when index is out of range)
How do you implement an iterator for ArrayIndexedList?
1) add a new class ArrayIndexedListIterator: public class ArrayIndexedListIterator<T> { } 2) ArrayIndexedListIterator must implement the Iterator interface: public class ArrayIndexedListIterator<T> implements Iterator<T> { } 3) the hasNext and next operations from the Iterator interface are inherited (and need to be implemented) public class ArrayIndexedListIterator<T> implements Iterator<T> { @Override public boolean hasNext( ) { return false; } @Override public T next( ) { return null; } }
Consider adding the following method to the GradStudent class, which raises the compilation error "name has private access in Student". How can you resolve the error?
1) use getName( ) and getEmail( ) instead 2) change the visibility of name and email from private to protected or public in Student class Private fields/methods are inherited by a sub-class, but the inherited fields (or methods) that are declared private in a super-class are not directly accessible in sub-classes
What are interface nuances? (3)
1) we cannot have multiple inheritance in Java, but a class may implement more than one interface public class SomeClass implements InterfaceA, InterfaceB { } 2) a class can extend another (regular or abstract) class and implement one or more interfaces public class SomeClass extends OtherClass implements InterfaceA, InterfaceB { } 3) an interface itself can be a subtype of another interface in which case it is said that it extends the other interface public interface SomeInterface extends OtherInterface { }
How would you implement the methods in ArrayIndexedList?
@Override public T get(int index) { return data[index]; } @Override public int length( ) { return data.length;\ } @Override public put(int index, T value) { data[index] = value; }
Write a unit test for the length method
@Test void testLengthAfterConstruction( ) { IndexedList<Integer> numbers = new ArrayIndexedList<>(5, 10); assertEquals(5, numbers.length( )); IndexedList cannot be instantiated (because it is an interface) so we must use a concrete implementation of it (e.g. ArrayIndexedList). Therefore, the test is actually testing an IMPLEMENTATION of length
What is a class? What does it do? What is it used for?
A class defines the attributes, structure, and operations that are common to a set of objects, including how the objects are created. Student is a class, and we use it to make (instantiate) objects using the new operator ex: Student john = new Student("John, "[email protected]");
What is encapsulation?
A class provides an encapsulation by bundling related data (fields) and behaviors (methods) into one cohesive unit
What is a composite data type?
A composite data type is a type that is made up of other types. Ex: a Roster class that holds an array of Student objects, or represents a collection of students. A class like Roster is called a container class or an aggregate class
Data type and data structure
A data type consists of a type (a collection of values) together with a collection of operations to manipulate the type A data structure encapsulates organized mechanisms for efficiently storing, accessing, and manipulating data.
Overriding vs overloading
A different return type as the sole difference between two methods is NOT sufficient for overloading The overloaded method is usually in the same class, but it can also be in derived classes. The overriding must have the same signature as the overridden one in the super class (same return type or subtype) Overriding never happens in the same class. It always happens in sub-classes
What is type substitution?
A given type variable may be assigned a value of any subtype, and a method with a parameter of a given type may be invoked with an argument of any subtype of that type
What is a robust method?
A robust method is one that handles bad (invalid or absurd) inputs reasonably
What is a unit test?
A unit test is a term used in software engineering to refer to a test written to examine the smallest block of code that can be isolated for testing. In most programming languages, such a "unit" is a function/method
Abstract Data Types (ADT)
ADT is a description (representation) of some (type of data) and the operations that are allowed on that data, while abstracting (ignoring) implementation details ADT simply provides a minimal expected interface and set of behaviors without regard to how they will be implemented A data structure is an implementation of an ADT ex: the abstract class Roster can be seen as ADT for "roster" which lays out the interface of its core operations add, remove, and find. It is essential that these operations are not implemented (otherwise not an ADT). The responsibility of implementing the core operations falls on the data structures MoocRoster and JhuRoster
What is an unchecked exception?
All exceptions are checked unless they subtype the Error class or the RuntimeExceptions The compiler does not force you to handle unchecked exceptions. The compiler will allow you to call the method but it may potentially throw an unchecked exception A method that throws an unchecked exception does not need to include a throws clause in its declaration
How to implement an interface
Alliteration: implement interface - use of keyword implements - MoocRoster declares its fields (since the Roster interface does not include fields) and initializes them in its constructor (no super keyword)
What is an abstract class?
An abstract class is declared with the abstract keyword. it signals that it cannot be instantiated (even though it has a constructor) An abstract method is a method that is declared with the abstract keyword and without an implementation Any (non-abstract) sub-class that extends an abstract class is responsible for implementing its abstract methods Non-abstract methods can be implemented in an abstract class
How is an abstract type different from a regular class? What can it not be used as?
An abstract class is just like a regular (non-abstract) class except that: 1) it contains the keyword abstract in its declaration 2) it cannot be instantiated While an abstract class can be used as the apparent type of an object, it CANNOT be used as its actual type An abstract class may contain fields, constructors, and fully implemented methods, just like a regular class. An abstract class usually contains abstract methods, but it does not have to. A regular class cannot include abstract methods. An abstract class can be used as a parent class or extend another (regular or abstract class)
How many steps does binary search take?
An array has n elements. At each step, the search space is reduced by a factor proportional to the inverse of 2 raised to the power of the step. So the total number of steps binary search takes to finish its search, x, is proportional to the log base 2 n
Write the class for ArrayIndexedList which implements IndexedList (uses the built-in Java array as internal storage of data)
ArrayIndexedList is the first data structure
We want to make IndexedList work with types other than the integer. What is wrong about this approach? Change the data type of value from int to Object as in: void put(int index, Object value); Object get(int index);
Best option so far. Since every type (class) in Java is a subtype (sub-class) of Object, we can leverage type substitution and pass values of any type to the put method and return it from the get method Potential issues 1) when you retrieve a value from get, you must explicitly downcast it to its actual type (unless you only need to use the methods defined in Object). Note: Java automatically upcasts the argument to the Object type when using put 2) you can potentially store values of different types in an instance of IndexedList. However, this feature is generally undesirable. For example, supposed you have an IndexedList called apples. In this list, you want to store items of type Apple and its subtypes like McIntoshRed and GoldenDelicious. You do not want to store items of type Orange in apples
What changed in the IndexedList ADT now that it extends Iterable?
By inheritance, the IndexedList ADT now contains the following method declaration (inherited from the Iterable interface) Iterator<T> iterator( ); Any class that implements IndexedList (such as ArrayIndexedList) must provide an implementation for the iterator method
What kind of casting is used in this method?
Casting from Student to GradStudent is known as Downcasting, the typecasting of a parent object to a child object When an object of type GradStudent is passed as an argument to greetAdvisor, the compiler implicitly casts it to Student. The typecasting of a child object to a parent object is known as Upcasting
Write IndexedList ADT with a generic base type
Changes: - interface name is appended with <T> - the data type of value is changed to T - the return type of get is changed to T T is a placeholder for any type for which a user might want to use IndexedList Generic parameters provide a way for you to re-use the same code with different types
What are the two types of exceptions?
Checked and Unchecked exceptions
Suppose we declared Student jane and GradStudent john. Which of the following are not valid Java statements?
D The apparent type of an object cannot be a subtype of its actual type
Why would you declare a property with a visibility modifier or protected?
Declare a property with a visibility modifier or protected if you want to access it directly in derived classes. The protected modifier indicates that the property is visible to sub-classes but hidden from clients. Use sparingly. For fields, particularly, you don't need direct access in most cases and are better off using getters/setters to access them.
What field would you need in ArrayIndexedList? How would you declare it
Define the fields with a generic type. Here we need a generic array. private T[ ] data;
What is the Object class?
Every class in Java is descended from the Object class. This is an implicit inheritance. And since the Object class contains a toString( ) method, we can call toString( ) on any programmer-defined type and get its string representation. The default behavior of toString( ) is often overridden to return a different string representation of the object. The Object class has several other methods, namely equals and hasCode
What is a has-a relationship?
Has-a relationship (composition) between types (classes Composition is observed when one type is made up of other types. It can be used to achieve code reuse and polymorphism ex: the Roster class is made up of students. Roster has-a Student
How can type substitution be used here?
If GradStudent is declared as a subtype of Student, the (original) Roster class (as defined in prev. chapter) needs to changes at all. You can add/remove grad students by leveraging type substitution Since we can substitute GradStudent for Student, we can: - have one student array of type Student and store both objects of Student and GradStudent in it - have one pair of add/remove methods that take a parameter of type Student and invoke it by passing either an object of Student or GradStudent - have one find method that returns an object of type Student, and use it to search both grad and non-grad students
What is a checked exception and how should you handle it?
If a method throws a checked exception, the compiler will not let you simply call it. You must handle the exception by either 1) using a try/catch block 2) allow the method to throw an exception. A method that throws a checked exception must include a throws clause in its declaration Java verifies checked exceptions at compile-time and forces you to provide a handling mechanism for it
Based on the completed diagram, make up an example to showcase polymorphism
Imagine there is an area method in the Shape interface. This method must be implemented appropriately in the Circle and Square classes public static void printArea(Shape s) { System.out.println(s.area( )); } The following code exhibits polymorphism: Circle ci = new Circle(2); Square sq = new Square(3); printArea(ci); printArea(sq); Static polymorphism: during compile-time, ci and sq are implicitly upcasted to Shape when printArea is called Dynamic polymorphism: JVM dispatches the correct implementation of s.are( ) based on the ACTUAL type of s (which is, for example, Circle when ci is passed to printArea)
Linear Search
Implement linear search to find a student with a certain email (assume all student emails are unique) NOTE: use .equals to compare two strings (not ==). Generally speaking, you should not use == for non-primitive types because with ==, you are comparing memory locations on objects, not their "values"
Information hiding principle and how is it used in this code
Information hiding principle: to prevent certain aspects of a class from being accessible to its clients. It shifts the code's dependency onto a well-defined interface ex: clients of Roster class would use find with one parameter email another common way where information hiding manifests itself is by making your class attributes (fields) inaccessible from the outside while providing getter and setter methods for attributes that shall be readable/updatable by other classes
What is an is-a relationship? What is it used for?
Inheritance should be used to model "is-a" relationships. Code reuse is an added advantage. ex: GradStudent is a Student with added attributes and/or behaviors
What is @BeforeEach and how should it be used?
Instead of writing: IndexedList numbers = new ArrayIndexedList<>(5, 10); in every unit test, you can use a setup method @BeforeEach that will be run before each unit test
We want to make IndexedList work with types other than the integer. What is wrong about this approach? Overload the put and get methods for different data types
It's possible to overload put with different data types for value. However, we cannot overload get by varying its return type because changing the return type is not enough for overloading Even if this was possible, we would only account for types already defined. In other words, IndexedList will not work for programmer-defined types that it does not have an overloaded version of. Assuming we knew all the data types in advance, this would be an inelegant solution, that would contain hundreds of overloaded methods
How can you access jane's advisor?
Jane does have an advisor (since she is a GradStudent) and you can get the advisor information out of jane by casting types greetAdvisor is defined in other classes. greetAdvisor uses Student and GradStudent if the argument provided to greetAdvisor was not instantiated as GradStudent, then the method will break during runtime
How can this line of code be divided into a declaration and instantiation of jane? Student jane = new GradStudent("Jane", "[email protected]");
Jane is declared as student, but instantiated using GradStudent Student jane; //declare jane's type is "Student" jane = new GradStudent("Jane", "[email protected]"); //instantiate jane as GradStudent the disparity between types is allowed (as long as GradStudent is a subtype of Student)
How does overloading and overriding relate to static and dynamic polymorphism?
Java decides at COMPILE time which version of an overloaded method must be invoked (static polymorphism) Java decides at RUNTIME which version of an overridden method shall be dispatched (dynamic polymorphism)
Multiple inheritance?
Java does not support multiple inheritance, where one class has more than one super-class and inherits features from all parent classes Note that it is perfectly ok for a class to have multiple sub-classes
How to extend an abstract class
No abstract keyword in the class declaration nor method declaration. The override annotation is used for methods MoocRoster has access to students and numStudents in Roster since those fields were defined as protected MoocRoster's constructor invokes the constructor of Roster (using super(size)), which constructs the students array and initializes the numStudents attribute
How do you declare IndexedList now, when it was made with a generic base type
Now when declaring IndexedList, you must specify the intended base type: IndexedList<Integer> numbers; IndexedList<Apple> apples; When you declare numbers as IndexedList<Integer>, you signal your intention to the compiler. All values stored in numbers must be of type Integer. in turn, the compiler will 1) ensure that (providing type safety), so attempting to store, e.g. a string in numbers will result in a compile-time error 2) not to bother you to (down) cast a value retrieved from the ADT (e.g., through using the get method here)
What is an aggregate object?
Object that has objects inside of it, also known as a collection
Which of these lines of code will cause a compiler error and why? Roster class is an Abstract class, JhuRoster and MoocRoster extend Roster
Roster myRoster = new Roster(50); will cause a compiler error
Can we redefine Roster and use GradStudent in place of Student (in declaration of fields/parameters data types) to achieve the same effect?
Since inheritance is not symmetric, we would not be able to achieve the same effect if we were to define Roster and use GradStudent in place of Student (in the declaration of fields/parameters data types)
What is a disadvantage of declaring an object to their base type?
Student jane = new GradStudent("Jane", "[email protected]"); GradStudent matt = new GradStudent("Matt", "[email protected]"); The declaration of jane is similar to the case where we have an array of students and add objects of type GradStudent to it Student[ ] students = new Student[10] students[0] = new GradStudent("Jane", "[email protected]"); Disadvantage: cannot access the advisor of jane matt.getAdvisor( ); // works fine jane.getAdvisor( ); // Compiler error: Cannot resolve method 'getAdvisor' Since jane (the object) is DECLARED as a Student (and not a GradStudent), its behavior (i.e. what it does, what operations/methods can be invoked on it) is limited to those declared in the Student class
Dynamic (Runtime) Polymorphism
The Java Virtual Machine (JVM) decides at runtime which method to dispatch Method dispatch: the process to decide which implementation of a method to use when there are multiple implementations available (as a result of method overriding) Dynamic polymorphism relates to the ability of a child class to override the behavior of its parent class
What does the apparent type determine and what does the actual type determine?
The apparent type determines what the object can do, while the actual type determines how the object will behave
When a class implements an interface, does it have to implement all its methods?
The class must implement all its methods unless it is an abstract class. In this case, it can defer the implementation of those methods to its sub-classes
How do you write a constructor for a child class?
The constructors of a super-class, unlike fields and methods, are not inherited by a sub-class. You must define non-default constructors of a sub-class. The constructors of the sub-class can invoke the constructors of the super-class using the super keyword Call to super( ) must be the first statement in the sub-class constructor You can update (or overload) the constructor of GradeStudent to take an initial value for advisor public GradStudent(String name, String email, String advisor) { super(name, email); this.advisor = advisor; }
What is the iterator design pattern
The iterator design pattern states the elements of a collection (an aggregate object) should be accessed and traversed WITHOUT EXPOSING its representation (underlying implementation) This goal is achieved by defining an iterator object to traverse a data structure and access its elements Iterator pattern hides the actual implementation of a data structure from the clients of it. To implement the iterator pattern, Java API provides two interfaces: Iterable and Iterator
In this code, identify examples of method overloading vs method overriding. Identify examples of static vs dynamic polymorphism.
The makeSound method is overloaded in the Animal class, and it is overridden in the Dog and Cat classes Static polymorphism: the objects of (actual) type Dog and Cat are stored in an array with a declared type of Animal Dynamic polymorphism: makeSound(2) inside the for-loop will need to call to overloaded makeSound (without argument). During runtime, the dispatch of makeSound will be based on the actual type of the Animal object 'a'
We want to make IndexedList work with types other than the integer. What is wrong about this approach? Use method overriding to provide multiple concrete implementations of IndexedList that work for different data types
To override methods, the method's signature being overridden in a sub-class must be consistent with the overriding one in the parent class. So, we will not be able to override, e.g. put in a sub-class and accept values of type boolean instead of int
How should you organize catch blocks when dealing with exception hierarchy?
When you chain catch blocks, you must deal with more SPECIFIC exceptions first because if an exception is declared to be caught, any of the sub-classes of that exception will also be caught my that same catch statement ex: try { // some code that might throw BankingException exception or its sub-classes } catch (InsufficientFundsException e) { // deal with the exception } catch (BankingException e) { // deal with the exception }
How can one pass primitive types (int, float, char, etc) to a method expecting Object?
You cannot do that. However, every primitive type in Java has a corresponding reference type. ex: int has integer wrapper class that provides a way to use primitive type int as an Object
What is a data structure?
a data structure encapsulates organized mechanisms for efficiently storing, accessing, and manipulating data Data structure means an organization or structuring for a collection of data types ex: Roster is a data structure
What is an algorithm?
a process or set of rules to be followed in calculations or other problem-solving operations, especially by a computer
What is an object?
an instance of a class. An object represents an individual, identifiable item, unit, or entity (either real or abstract) with a well-defined role in the problem domain
Best and worse case scenario for binary search
best case: first element you look at worst case: log base 2 N (where N is the number of elements in the array)
Best and worse case scenarios of the linear search
best case: the target we are looking for is the first element in the array, then we find it immediately worst case: the target is not in the array, then the linear search goes through all elements to report that the array does not contain what we are looking for
How do you write the constructor for ArrayIndexedList? Hint: need to instantiate and initialize the array data in a special way
data = (T[ ]) new Object[size]; Create an array of Object and then cast it to a generic array. Another syntax for creating a generic array is data = (T[ ]) Array.newInstance(Object.class, size); The statement: data = new T[size] DOES NOT WORK
What is a postcondition
describe expectations at the time the method exits
What is an invariant
describe the expected state for all objects of a class ex: the length method specifies Inv: length( ) >= 0 which means the length is always a non-negative value
Static (compile-time) polymorphism
ex: you pass an argument of type GradStudent to a method like add that takes a parameter of type Student bc the compiler honors type substitution and implicitly casts from the subtype (GradStudent) to the base type (Student) public class Shelter { private Animal[ ] animals; private int numAnimals; public add(Animal a) { animals[numAnimals++] = a; } } objects of type Dog and Cat can be passed to the add method and be stored in the animals array
What does the hasNext( ) method do in an iterator?
hasNext returns true if there is an element that we have not iterated over
Binary Search (under what conditions can it be used)
if the array is sorted and kept sorted as you add/remove to it, then you can use a more efficient search algorithm (than linear) called binary search. Binary search uses the knowledge that data is sorted to consider a (much smaller) subset of elements in finding the target.
What does calcPayment return?
mona gets more because ca.getHourlyPayRate( ) resolves to the overridden implementation in ExperiencedCourseAssistant class. In other words, JVM looks at the actual type of the ca object to figure out how getHourlyPayRate( ) is implemented JVM method dispatch starts at the instantiated/actual type and then looks up the hierarchy until it finds an implementation
Make up an example to showcase runtime polymorphism for the following type hierarchy
public class Animal { public void makeSound( ) { System.out.println("Grr..."); } } public class Cat extends Animal { @Override public void makeSound( ) { System.out.println("Meow"); } } public class Dog extends Animal { @Override public void makeSound( ) { System.out.println("Woof"); } } if we execute the following code Animals[ ] animals = new Animal[3]; animals[0] = new Animal( ); animals[1] = new Cat( ); animals[2] = new Dog( ); for (Animal a: animals) { a.makeSound( ); } it will print: Grr... Meow Woof JVM dispatches the implementation of makeSound according to actual type of 'a' at each iteration, at runtime
What is an IndexedList ADT?
public interface IndexedList { void put(int index, int value); int get(int index); int length( ); } The IndexedList ADT is an abstraction of list, a sequential collection of elements to which you can add and access (get) data using an index (a non-negative integer representing the position of data in the sequence)
Change this abstract class Roster into a Roster interface
public interface Roster { void add(Student s); void remove(Student s); Student find(String email); }
How do you declare that IndexedList ADT is iterable?
public interfact IndexedList<T> implements Iterable<T> { }
What is a precondition
requirements that must be met when entering a method. If a client violates this condition, they cannot expect the get method to behave as expected
Exception hierarchies
the Throwable class is the super-class of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its sub-classes) are thrown by the JVM or can be thrown by the Java throw statement Exceptions are regular classes, and such, one exception can sub-class another
How is the built-in array special?
the built-in array is an exception because it is an iterable (thus can be used with the enhanced for loop) but does not implement the iterable interface. the built-in array is a unqiue construct, a cross between primitive and objects
What does the next( ) method in an iterator?
the next method returns the current element and then moves the cursor to the next element Iterator<MyType> it = myCollection.iterator( ); while (it.hasNext( )) { MyType element = it.next( ); // do something with element } // the for loop is the same as the one below for (MyType element : myCollection) { // do something with element) }
Normal vs enhanced for loop
typical approach to step through all elements of an array in order for (int i = 0; i < myArray.length; i++) { System.out.println(myArray[i]); } enhanced for loop: // colon can be read as "in" for (int element : myArray) { System.out.println(element); } the enhanced for loop is a simple way to iterate through all the elements of a collection (not just arrays but other data structures built into Java). It is important to note that not all data structures are "positional"; for example, there is no notion of position in a Set. So the enhanced loop abstracts the idea of traversing the data structure elements
Implement binary search for the roster class to find a student with a specific email
use recursion
Write the documentation comments for IndexedList (include preconditions, postconditions, and invariants)
void put(int index, int value); - change the value at the given index - @param index representing a position in this list. Pre: 0 <= index < length - @param value to be written at the given index. Post: this.get(index) == value int get(int index); - retrieve the value stored at the given index - @param index representing a position in this list. Pre: 0 <= index < length - @return value at the given index int length( ); - get the declared capacity of this list - @return the length. Inv: length( ) >= 0
Apparent vs actual type
when you declare a variable (SomeClass obj), you are setting its apparent type to be the declared type when you instantiate an object (obj = new SomeClass( ) ) you are setting its actual type to be the instantiated type The apparent type of Jane is Student, while its actual type is GradStudent Type substitution allows the actual type of an object to be the instantiated type
Method overriding
when you override a method in a sub-class: 1) the overriding method must have the same signature (name and parameters) as the overridden one in the super-class 2) it must have the SAME RETURN TYPE as the overridden one. Although, it could return a SUBTYPE of what is returned by the overridden method in the super-class 3) it must be at least as visible as the overridden method. It is possible (yet strong discouraged) to take a private or protected method and override it to a public one in the sub-class. The reverse is not possible; you can't override a public method to a protected or private one