Programming paradigm (fundamental style): OOP, imperative (emphasizing state changes) and functional (emphasizing use of functions)
 Functional programming example: int sum = Enumerable.Range(1, 9).Where(i => i % 2 == 0).Sum();
 Imperative programming example: for (int i = 1; i < 10; i++) if (i % 2 == 0) sum += i;
 OOP: using objects in programming with object data fields, methods and their interaction
 OOP features: data abstraction, encapsulation, message passing, modularity, polymorphism, and inheritance
 Abstraction: what to expose, what to hide
 Data abstraction: factoring out details
 Information hiding: the principle of segregation of the design decisions
 Information hiding example: Weights.Compare(Weight argWeight1, Weight argWeight1)
 Encapsulation: enclosing in a capsule or object, a technique in information hiding
 Encapsulation example: Box box1 = new Box(); if (box1.Heavier(box2)) { }
 Messaging passing: objects or processes can wait for messages from others
 Process synchronization: multiple processes agreeing to a sequence of action
 Modularity: separation of concerns (features and behaviors)
 Coupling: degree of interdependencies between modules or classes
 Cohesion: how much functions or methods within a module are related to another
 Low coupling: classes should loosely dependent like lego pieces
 High cohesion: methods highly related like jigsaw puzzle pieces
 Low coupling and high cohesion: classes like lego, methods like jigsaw puzzle
 Polymorphism: objects from different types responding to calls by the same name, e.g. operator overloading for addition
 Inheritance: code reuse by establishing a subtype from an existing object
 Inheritance example: class Employee extends Resident extends Person
 Method overriding: providing a method with same name, signature, and return type as that of the parent class
 Keyword 'internal' in C#: Friend in C++ is not your friend