Object-oriented

The three basic features of object-oriented are: encapsulation, inheritance, and polymorphism.

Class & Instance


  • Class is an object template, instance is an object instance
  • Define class (contains multiple fields, field)
1
2
3
4
class Person {
public String name;
public int age;
}
  • Create instance (variables that point to instance are reference variables)
1
Person ming = new Person();
  • Access instance variables with Variable. Field
  • A Java source file can contain multiple class definitions, but only one public class can be defined, and the public class name must match the file name. If you want to define multiple public classes, you must split them into multiple Java source files

Method


  • Motivation: To avoid external code to access field directly, we can modify field with private to deny external access, and then use method to allow external code to modify field indirectly
    • Inside the method, we have the opportunity to check if the parameters are correct; external code does not have any opportunity to set the field to an unreasonable value
    • By defining methods, a class can expose to external code the interface for some operations, while ensuring internal logic consistency
    • The syntax for calling a method is Instance variable. Method name (parameter);
  • Defining methods
1
2
3
4
5
6
7
8
9
// modifier method return type method name (list of method parameters) {
// Several method statements;
// return method return value;
// }
// If there is no return value and the return type is set to void, return can be omitted

public String getName() {
return this.name;
}
  • private methods: external calls are not allowed, only the inside of the class can be called
  • this variable: Inside the method, you can use an implicit variable this, which always points to the current instance. The fields of the current instance can be accessed through this.field.
    • If there is no naming conflict, this can be omitted; if local variables and fields are renamed, this must be added
  • Method parameters: 0 or any of them, used to receive the value of the variable passed to the method
  • Variable parameters: type..., equivalent to an array type
    • Variable parameters ensure that null cannot be passed in
  • Parameter binding
    • The passing of a basic type parameter is a copy of the caller’s value. Each side’s subsequent modifications do not affect each other
    • With reference type arguments, the caller’s variable and the receiver’s argument variable point to the same object. Any modification of this object by either side affects the other (because it points to the same object)

Construction method


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Main {
public static void main(String[] args) {
Person p = new Person("Xiao Ming", 15);
}
}

class Person {
private String name;
private int age;

// Construction method
public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return this.name;
}

public int getAge() {
return this.age;
}
}
  • When an instance is created, the new operator calls its corresponding constructor method, which is used to initialize the instance
    • The instance is actually created by the constructor method to initialize the instance
    • The name of the constructor method is the class name.
    • There is no restriction on the parameters of the constructor method, and you can write any statement inside the method. However, compared to normal methods, constructor methods do not have a return value (nor void), and to call a constructor method, you must use new.
    • If no constructor method is defined, the compiler will automatically create a default constructor method with no parameters.
    • When fields are not initialized in the constructor method, the default value is null for fields of reference types, 0 for fields of numeric types, and 0 for int types.
      and the default value for boolean types is false.

Multi-construction methods

  • Multiple constructors can be defined, and the compiler will automatically determine them based on the parameters.
  • You can call another constructor inside a constructor method for easy code reuse.

Overload


1
2
3
4
5
6
7
8
9
10
11
12
// The String class provides several overloaded methods indexof()
public class Main {
public static void main(String[] args) {
String s = "Test string";
int n1 = s.indexOf('t');
int n2 = s.indexOf("st");
int n3 = s.indexOf("st", 4);
System.out.println(n1);
System.out.println(n2);
System.out.println(n3);
}
}
  • Meaning: Method overloading refers to multiple methods with the same method name but different parameters.
  • Function: Methods with similar functions use the same name, which is easier to remember and simpler to call.
  • The return value type of method overloading is usually the same

Inheritance


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person {
private String name;
private int age;

public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}

class Student extends Person {
// Do not duplicate the name and age fields/methods,
// only need to define new score fields/methods
private int score;

public int getScore() { … }
public void setScore(int score) { … }
}
  • Function: Reuse code
  • Use the extends keyword to implement inheritance
  • Inheritance tree: for classes that do not explicitly write extends, the compiler will automatically add extends Object.
    • Any class, except Object, inherits from some class
    • A class has one and only one parent class. Only Object is special, it has no parent
  • Subclasses can’t access the parent’s private, they can access the parent’s protected.
  • If the parent class does not have a default constructor, the subclass must explicitly call super() with arguments in order for the compiler to locate a suitable constructor for the parent class
    • The subclass does not inherit any of the parent’s constructor methods. The default constructor of a subclass is automatically generated by the compiler and is not inherited

Blocking Inheritance

1
2
3
4
public sealed class Shape permits Rect, Circle, Triangle {
...
}
// The above Shape class allows only 3 specified classes (Rect, Circle, Triangle) to inherit from it
  • From Java 15, use -sealed to modify the class and explicitly write the names of subclasses that can inherit from the class via -permits
    • sealed is currently in preview state, to enable it, you must use the parameters -enable-preview and -source 15

Upcasting

1
Person p = new Student();
  • Safely transforming a subtype into a more abstract parent type
    • For example, if the inheritance tree is Student > Person > Object, then you can transform the Student type to Person, or to a higher level Object

Downcasting

1
2
3
4
5
Person p = new Student();
if (p instanceof Student) {
// Downcasting only if judged successful
Student s = (Student) p; // It will work!
}
  • It will probably fail. To avoid errors, use instanceof to first determine whether an instance is of a certain type or not
  • Starting from Java 14, after determining instanceof, you can directly transform to the specified variable and use it directly to avoid forcing transformation again

Inheritance & Combination

  • Inheritance is an “is” relationship and combination is a “has” relationship

Polymorphism


1
2
3
4
5
6
7
8
9
10
11
12
13
class Person {
public void run() { … }
}

class Student extends Person {
@Override
public void run() { … }
}

class Teacher extends Person {
@Override
public void run() { … }
}
  • Meaning: method calls for a certain type, where the actual method executed depends on the actual type of method at runtime
  • Function: Allows adding more types of subclasses to extend the functionality without modifying the code based on the parent class

Override

  • Subclasses can override the methods of the parent class. The override changes the behavior of the parent class methods in the subclass.
    • Adding @Override allows the compiler to help check if the override is done correctly.
  • If you want to call the overridden method of the parent class in the overriding method of the subclass, you can do so with super.
  • final
    • final-modified methods can be prevented from being overridden
    • A class modified by final prevents inheritance.
    • final-modified fields must be initialized when the object is created and cannot be modified subsequently

Abstract Class


1
2
3
abstract class Person {
public abstract void run();
}
  • Motivation: If the method of the parent class itself does not need to achieve any function, only to define the method signature, the purpose is to allow subclasses to override it, then the method of the parent class can be declared as an abstract method, itself does not achieve any method statement
  • Meaning: If a class defines a method, but no concrete implementation code, the method is an abstract method, abstract methods are modified with abstract; because the abstract method can not be implemented, so the class must also be declared as an abstract class (abstract class)
    • abstract class can not be instantiated
  • Function: The abstract class can force subclasses to implement its defined abstract methods, otherwise the compilation will report an error. It is equivalent to defining a “specification”

Abstract-oriented programming

  • Upper level code only defines the specification
  • Business logic can be implemented without subclasses (normal compilation)
  • The specific business logic is implemented by different subclasses and the caller does not care

Interface


1
2
3
4
interface Person {
void run();
String getName();
}
  • Motivation: If an abstract class has no fields and all methods are all abstract methods, you can rewrite the abstract class as an interface
    • An interface is a purely abstract interface that is more abstract than an abstract class, because it cannot even have fields
  • Declare an interface using interface.
  • When a concrete class implements an interface, the implements keyword is used; a class can implement more than one interface.
  • Interfaces are also data types, and are suitable for both upward and downward transitions

Interface Inheritance

1
2
3
4
5
6
7
8
interface Hello {
void hello();
}

interface Person extends Hello {
void run();
String getName();
}
  • Using extends
  • Inheritance relationship
    • The public logic fits in the abstract class, the concrete logic is placed in each subclass, and the interface level represents the level of abstraction
    • The object instantiated can only ever be a concrete subclass, but always refer to it through the interface, because interfaces are more abstract than abstract classes

Default method

  • Interfaces can define default methods
  • Motivation: When we need to add a new method to an interface, it will involve modifying all the subclasses. If the new method is a default method, then the subclasses do not need to be modified, but only need to override the new method where it is needed.
  • The difference between default method and abstract class ordinary method: because interface has no fields, so default method can not access the fields, while the abstract class ordinary method can access the instance fields

Static Fields & Static Methods


Static Fields

  • Fields modified with static are called static fields
  • Instance Fields & Static Fields
    • Instance fields have their own separate “space” in each instance, and fields of the same name in each instance do not affect each other
    • Static fields have only one shared “space”, which is shared by all instances
  • It is not recommended to use `instance variables. Static fields’ to access static fields, it is recommended to use class names to access static fields
    • Static fields can be interpreted as fields describing the class itself (not instance fields)

Static methods

  • Methods that are modified with static are called static methods
  • Instance Methods & Static Methods
    • To call an instance method, you must pass an instance variable.
    • To call a static method, you don’t need an instance variable, you can call it by the class name. Static methods are similar to functions in other programming languages
  • Static methods do not require an instance and cannot access this, but they can access static fields and other static methods
  • Static methods are often used in tool classes (e.g. Arrays.sort(), Math.random()) and auxiliary methods (e.g. the entry point of a Java program, main(), is a static method)

Static fields for interfaces

  • interface can have static fields, and the static fields must be of type `final
  • Since interface fields can only be of type public static final, these modifiers can be removed

Package


1
2
3
4
package ming; // Affirmation of package name ming

public class Person {
}
  • When defining a class, you need to declare in the first line which package the class belongs to
  • A class always belongs to a package (package), the class name (e.g. Person) is just a shorthand, the real full class name is package name. Class name
    • As long as the package name is different, the class is different
    • Packages can be multi-layer structures, separated by . separated by
    • Packages have no inheritance relationship
    • class without package name defined is the default package, very easy to cause name conflicts, not recommended to not write package name

Package Scope

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package hello;

public class Person {
// Package Scope
void hello() {
System.out.println("Hello!");
}
}

public class Main {
public static void main(String[] args) {
Person p = new Person();
p.hello(); // Can be called, because Main and Person are in the same package
}
}
  • Classes located in the same package can access the fields and methods of the package scope
  • Fields and methods that are not modified by public, protected, or private are package scoped

import

1
2
3
4
5
6
7
8
9
10
11
// Person.java
package ming;

// Import the full class name
import mr.jun.Arrays;

public class Person {
public void run() {
Arrays arrays = new Arrays();
}
}
  • The core classes of the JDK use the java.lang package, which is automatically imported by the compiler
  • Other common classes of the JDK are defined in java.util.*, java.math.*, java.text.*, ……

Scope


public

  • class, interface defined as public can be accessed by any other class
  • field, method defined as public can be accessed by other classes, provided that they have access to class first
  • If you’re not sure whether you need public, don’t declare it as public, i.e. expose as few fields and methods as possible to the public
  • A .java file can contain only one public class, but can contain multiple non-public classes. If there is a public class, the file name must be the same as the name of the public class

private

  • field, method defined as private cannot be accessed by other classes
  • Access to private is restricted to the interior of class and is independent of the order of method declarations ***. It is recommended to put private methods later
  • Nested classes have access to private.

protected

  • Acts on inheritance relationships. Fields and methods defined as protected can be accessed by subclasses, as well as subclasses of subclasses

pakage

  • Package scope means that a class is allowed to access class without public, private modifier of the same package, as well as fields and methods without public, protected, private modifier
  • Defining methods as package permissions helps to test

Local Variables

  • Variables that are defined inside a method are called local variables
  • The scope of a local variable starts at the point where the variable is declared and ends at the corresponding block
  • Method parameters are also local variables
  • The scope of local variables should be kept as small as possible, and local variables should be declared as late as possible.

final

  • Use final to prevent inheritance, overwriting by subclasses, and reassignment

Nested Class


Inner Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) {
Outer outer = new Outer("Nested"); // Instantiate an Outer
Outer.Inner inner = outer.new Inner(); // Instantiate an Inner
inner.hello();
}
}

class Outer {
...
class Inner {
// Define an Inner Class
...
}
}
  • An instance of Inner Class cannot exist alone, it must be attached to an instance of Outer Class
    • To instantiate an Inner, you must first create an instance of Outer, and then, call new on the Outer instance to create the Inner instance
  • Inner Class can modify the private field of the Outer Class
  • The Outer class is compiled as Outer.class, while the Inner class is compiled as Outer$Inner.class

Anonymous Class

1
2
3
Runnable r = new Runnable() {
// Implement the necessary abstract methods...
};
  • Another way to define an Inner Class. It is not necessary to define this Class explicitly in Outer Class
    • Motivation: Because we don’t care about the class name here, we can write much less code than defining the Inner Class directly.
  • Anonymous classes can also access the private fields and methods of the Outer Class
  • Anonymous classes are compiled as Outer$1.class, Outer$2.class, Outer$3.class
  • In addition to interfaces, anonymous classes can also inherit from ordinary classes
  • Inner Class and Anonymous Class are essentially the same, both must depend on an instance of Outer Class, i.e., they implicitly hold an instance of Outer.this and have private access to Outer Class

Static Nested Class

  • No longer attached to an instance of Outer, but a completely separate class, so it cannot refer to Outer.this, but can access Outer‘s private static fields and static methods
  • Static Nested Class is a separate class, but has private access to Outer Class

Classpath and jar


  • The JVM determines the path and order of searching for class through the environment variable classpath.
  • Setting the system environment variable classpath is not recommended, it is always recommended to pass in the -cp command.
  • The jar package is equivalent to a directory, and can contain many .class files for easy download and use

Class version


  • A higher version of the JDK can compile and output a lower version compatible class file, and vice versa may report an error
  • Which JDK version is used at runtime, try to use the same version to compile the source code when compiling

Modules


  • The .class file is the smallest executable file seen by the JVM, and a large program needs to write many Classes and generate a bunch of .class files. The jar file is the container for the class files, for ease of management. It does not care about the dependencies between `classes
  • Since Java 9, modules have been introduced, and the class container with its own “dependencies” is the module, which is identified by the .jmod extension
  • Only the java.base module does not depend on any module and is the “root module”
  • Wrapping a bunch of classes into a jar is just a packaging process, while wrapping a bunch of classes into a module requires not only packaging, but also writing dependencies, and can contain binary code (usually JNI extensions) and support multiple versions
  • The role of modules: declare and manage dependencies; further isolate access to code

Appendix


Tutorial

Liao Xuefeng’s Java course - Object-oriented Foundation

Dec 2022 Intro to Java

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×