Inheritance: When one class inherits from another class, the second class gains the state and behavior from the previous class. The second class can have additional state and behavior that the previous class does not have. The second class is called the subclass and the previous class is called the superclass. In java, we say that the subclass extends the superclass. Inheritance establishes an "is-a" relationship, i.e. an object of the subclass type is also an object of a superclass type (but no vice versa). -------------------- When it comes to inheritance, there may be two different types. A compile time type and a runtime type. The compile time type is the type of the reference variable that references an object. THe runtime type is the type that the Object was really created to be. When the runtime type and compile time type aren't the same, only methods that the compile type has can be called through the reference variable. The action of a reference variable of a superclass type being set to reference an object of a subclass type is called upcasting. Upcasting always works and can be done without any explicit cast. The action of take a reference variable whose runtime type is the subclass type but whose compile time is the superclass type and taking a reference variable of the subclass type and assigning it to the object is called downcasting. Downcasting only works with an explicit cast. Java has a mechanism called dynamic method lookup. When the subclass overrides a method in the superclass, even a subclass object is upcast, java will call the runtime type method. I.e. java will find the most specific method it can, and will call it! Polymorphism is when a piece of code can run in multiple different ways depending on what the runtime type of variables input to it are. -------------------------------------------------- Evaluating Expressions Goal: to write a system that is capable of evaluating arbitrary mathematical expressions whose building blocks are constants, addition, and multiplication. We will also assume that there's no ambiguity of evaluation. We will create an Expression interface to define an expression. An Expression is any class that has an evaluate() method. public int evaluate(); We will create constant expressions, binary expressions, unary expressions. e.g. 2 + 3 (2 + 3) + 4 ((3 * (4+5)) * (4 + 8)) + 7 (3! * 70) + 4