An abstract class

Abstract methods and abstract classes

Abstract methods and classes must be defined using the abstract modifier. Classes with abstract methods can only be defined as abstract classes. Abstract classes can have no abstract methods.

The rules are as follows:

  • Abstract classes and methods must use the abstract modifier. Abstract methods cannot have a method body.
  • An abstract class cannot be instantiated. An abstract class cannot create an instance even if it does not contain an abstract method.
  • An abstract class can contain five components: member variables, methods (both ordinary and abstract), constructors, initializer blocks, and inner classes (interfaces, enumerations). The constructor of an abstract class cannot be used to create instances, but is mainly used to be called by its subclasses;
  • A class that contains abstract methods (including directly defining an abstract method, inherits an abstract superclass but does not fully implement the abstract method contained in the superclass, and implements an interface but does not fully implement the abstract method contained in the interface) can only be defined as an abstract class.
public abstract class Shape
{
	// Initialize the block
	{
		System.out.println("Execute Shape initializer block...");
	}
	
	// Member variables
	private String color;
	
	// Define an abstract method to calculate the perimeter
	public abstract double calPerimeter(a);
	// Define an abstract method that returns a shape
	public abstract String getType(a);
	
	// Common method
	public void test(a)
	{
		System.out.println("Ordinary method");
	}
	
	// Define the constructor for Shape. This constructor is not used to create Shape objects, but is used to be called by subclasses
	public Shape(a){}
	public Shape(String color)
	{
		System.out.println("The constructor that executes Shape...");
		this.color = color;
	}

	public void setColor(String color)
	{
		this.color = color;
	}
	public String getColor(a)
	{
		 return this.color; }}Copy the code

An abstract class cannot be used to create instances. It can only be inherited as a parent class:

public class Triangle extends Shape
{
	// Define the three sides of a triangle
	private double a;
	private double b;
	private double c;

	public Triangle(String color , double a , double b , double c)
	{
		super(color);
		this.setSides(a , b , c);
	}

	public void setSides(double a , double b , double c)
	{
		if (a >= b + c || b >= a + c || c >= a + b)
		{
			System.out.println("The sum of the two sides of a triangle must be greater than the third.");
			return;
		}
		this.a = a;
		this.b = b;
		this.c = c;
	}
	// Overwrite Shape's abstract method for calculating perimeter
	public double calPerimeter(a)
	{
		return a + b + c;
	}
	// Overrides the abstract method of Shape that returns a Shape
	public String getType(a)
	{
		return getColor() + "Triangle"; }}Copy the code

When a class is modified with abstract, it indicates that the class can only be inherited. When a method is decorated with abstract, it indicates that the method must be implemented (that is, overridden) by a subclass. Final-modified classes cannot be inherited, and final-modified methods cannot be overridden. Therefore, final and abstract can never be used together;

In addition, when using static to decorate a method, it indicates that the method belongs to the class itself. That is, the method can be called from the class, but if the method is defined as an abstract method, it will result in an error when the method is called from the class (calling a method without a method body will definitely result in an error). Therefore, static and abstract methods cannot both modify a method, i.e., there is no class abstract method;

Note: Static and abstract are not mutually exclusive. While static and abstract cannot both modify a method, they can both modify an inner class.

Note: The method modified by the abstract keyword must be overridden by its subclass to be meaningful, otherwise the method will never have a body again. Therefore, the abstract method cannot be defined as private access.

Java8 interface

Introduction to the

An interface cannot contain ordinary methods. All methods in an interface are abstract methods. Java8 improves interfaces by allowing you to define default methods in the interface that provide method implementations.

Definition of an interface

  • The modifier can be public or omitted. If the public access control is omitted, the package access control is used by default. That is, only the same package structure can access the interface.
  • The interface name and the class name use the same naming rules.
  • An interface can have multiple direct parent interfaces, but interfaces can only inherit interfaces, not classes.

An interface cannot contain constructor and initialization block definitions. An interface can contain member variables (only static constants), methods (only abstract method instances, class methods, or default methods), inner classes (including internal interfaces, enumerations) definitions.

All members of an interface, including constants, methods, inner classes, and inner enumerations, have public access. When you define an interface member, you can omit the access control modifier. If the access control modifier is specified, only the public access control modifier can be used.

For static constants defined in an interface, the system automatically adds static and final modifiers to these member variables. In other words, when a member variable is defined in an interface, it is always modified with the three modifiers, whether or not the public static final modifier is used. There are no constructors or initializers in the interface, so member variables defined in the interface can only be defined with default values.

// The system automatically adds the public static final modifier to member variables defined in the interface
int MAX_SIZE = 50;
public static final int MAX_SIZE = 50;
Copy the code

Methods defined in an interface can only be abstract methods, class methods, and default methods. Therefore, if the default method is not defined, the system automatically adds the abstract modifier to the normal method. Whether or not the public Abstract modifier is used, a common method in an interface is always modified with a public Abstract. Common methods in an interface cannot have a method implementation (method body); But class method, default method must have method implementation (method body);

public interface Output
{
	// Attributes defined in an interface must be constants only
	int MAX_CACHE_LINE = 50;
	// Only public abstract instance methods can be defined in the interface
	void out(a);
	void getData(String msg);
    
    // To define a default method in an interface, you need to use the default modifier. The default method always uses the public modifier.
	default void print(String... msgs)
	{
		for(String msg : msgs) { System.out.println(msg); }}// Define the default method in the interface
	default void test(a)
	{
		System.out.println("Default test() method");
	}

	// When you define a class method in an interface, you need to use the static modifier. Class methods always use the public modifier -- if not specified, the system automatically adds it;
	static String staticTest(a)
	{
		return "Class methods in an interface"; }}Copy the code

Inheritance of interfaces

Interface inheritance is different from class inheritance. An interface fully supports multiple inheritance. That is, an interface can have multiple parent interfaces.

interface interfaceA
{
	int PROP_A = 5;
	void testA(a);
}
interface interfaceB
{
	int PROP_B = 6;
	void testB(a);
}
interface interfaceC extends interfaceA.interfaceB    
{
	int PROP_C = 7;
	void testC(a);
}
public class TestInterfaceExtends 
{
	public static void main(String[] args)
	{ System.out.println(interfaceC.PROP_A); System.out.println(interfaceC.PROP_B); System.out.println(interfaceC.PROP_C); }}Copy the code

Using an interface

A class can implement one or more interfaces that use the implements keyword;

After a class implements one or more interfaces, it must fully implement (i.e. override) all the abstract methods defined in those interfaces. Otherwise, the class will retain the abstract methods inherited from the parent interface, and the class must also be defined as abstract;

Interfaces and abstract classes

Interfaces are similar to abstract classes in that they have the following characteristics:

  • Interfaces and abstract classes cannot be instantiated. They are at the top of the inheritance tree and are intended to be implemented and inherited by other classes.
  • Both interfaces and abstract classes can contain abstract methods, which must be implemented by ordinary subclasses that implement the interface or inherit from the abstract class.

Interfaces and abstract classes have the following differences in usage:

  • An interface can contain only abstract methods, default methods, and class methods. Abstract classes can contain normal methods entirely;
  • Only static constants can be defined in the interface, and ordinary member variables cannot be defined. Abstract classes can define both ordinary member variables and static constants.
  • The interface does not contain a constructor; An abstract class can contain constructors. Constructors in an abstract class are not used to create objects. Instead, subclasses call these constructors to complete the initialization of the abstract class.
  • The interface cannot contain an initialization block. But abstract classes can contain initializer blocks;
  • A class can have at most one direct parent, including abstract classes; But a class can directly implement multiple interfaces;

The inner class

A class defined inside another class is called an inner class. A class that contains an inner class is also called an outer class.

Defining an inner class differs from defining an outer class in two ways:

  1. You can use three more modifiers for external classes: private, protected, and static—–.
  2. Non-static inner classes cannot have static members;

Non-static inner class

Most of the time, inner classes are defined as member inner classes, not as local inner classes (inner classes defined in methods are called local inner classes). A member inner class is a class member similar to a member variable, method, constructor, and initialization block. Local inner classes and anonymous inner classes are not class members.

There are two types of member inner classes:

  1. Static inner classes: member inner classes that use static decoration are static inner classes;
  2. Non-static inner classes: member inner classes that do not use static decoration are non-static inner classes;
public class Cow
{
	private double weight;
	// Two overloaded constructors for the external class
	public Cow(a){}
	public Cow(double weight)
	{
		this.weight = weight;
	}
	// Define an inner class
	private class CowLeg
	{
		// Two properties of the inner class
		private double length;
		private String color;
		// Two overloaded constructors for the inner class
		public CowLeg(a){}
		public CowLeg(double length , String color)
		{
			this.length = length;
			this.color = color;
		}
		public void setLength(double length)
		{
			this.length = length;
		}
		public double getLength(a)
		{
			 return this.length;
		}
		public void setColor(String color)
		{
			this.color = color;
		}
		public String getColor(a)
		{
			 return this.color;
		}
		// Inner class methods
		public void info(a)
		{
			System.out.println("Current leg color is:" + color + "High," + length);
			// Directly access the external class's private property: weight
			System.out.println("This cow's leg is heavier than the cow:"+ weight); }}public void test(a)
	{
		CowLeg cl = new CowLeg(1.12 , "Black and white");
		cl.info();
	}
	public static void main(String[] args)
	{
		//Cow cow = new Cow(378.9);
		//cow.test();
		CowLeg c = new Cow(378.9).new CowLeg(1.12 , "Black and white"); // Either way is ok. The second way is more intuitivec.info(); }}Copy the code

Using a non-static inner class inside an outer class is not much different from using a normal class.

Class = ‘Cow’; class = ‘Cow’; class = ‘CowLeg’; class = ‘Cow’; class = ‘CowLeg’; That is, the class file for member inner classes (including static inner classes and non-static inner classes) is always of this form: OuterClass cowleg. class is a class file for the member inner class (including static inner classes and non-static inner classes). Class, which is a class file for the outer class Cow, and a class file for the inner class CowLeg. That is, the class file for member inner classes (including static inner classes and non-static inner classes) is always of this form: OuterClassInnerClass.class;

Private members of an external class can be accessed directly from a non-static inner class. This is because a non-static inner class object holds a reference to the outer class object it hosts;

When a variable is accessed inside a method of a non-static inner class. The system first looks for a local variable with that name in the method, and if so, uses it. If it does not exist, it looks for a member variable of that name in the inner class of the method. If so, it is used. If it does not exist, then it looks for a member variable of that name in the outer class of the inner class. If so, it is used. If the variable does not exist, a compilation error will occur: the variable cannot be found.

Therefore, if an outer class member variable or an inner class member variable has the same name as a local variable of a method in the inner class, we can distinguish it by using this or the outer class class name. This as a qualification:

public class DiscernVariable
{
	private String prop = "External class attribute";
	private class InClass
	{
		private String prop = "Inner class properties";
		public void info(a)
		{
			String prop = "Local variable";
			// Access the external class instance attribute via the external class name.this.varname
			System.out.println("Attribute values of external classes:" + DiscernVariable.this.prop);
			// Access the properties of the outer inner class instance through this.varname
			System.out.println("Inner class attribute values:" + this.prop);
			// Access local variables directly
			System.out.println("Attribute values of local variables:"+ prop); }}public void test(a)
	{
		InClass in = new InClass();
		in.info();
	}
	public static void main(String[] args) 
	{
		newDiscernVariable().test(); }}Copy the code

Members of a non-static inner class can access private members of an outer class, but not the other way around. If an external class needs to access members of a non-static inner class, it must explicitly create a non-static inner class object to call access to the instance members:

public class Outer
{
	private int outProp = 9;
	class Inner
	{
		private int inProp = 5;
		public void acessOuterProp(a)
		{
			// An inner class can directly access members of an outer class
			System.out.println("The value of the outProp property of the external class :"+ outProp); }}public void accessInnerProp(a)
	{
		// The outer class cannot directly access the inner class attributes
		// system.out. println(" inner class inProp property value :" + inProp);
		// To access inner class members, you must explicitly create inner class objects
		System.out.println("Value of inProp property of inner class :" + new Inner().inProp);

	}
	public static void main(String[] args)
	{
		// Execute the following code to create only the external class object, but not the inner class object
		Outer out = newOuter(); }}Copy the code

Java does not allow static members to be defined in non-static inner classes:

public class InnerNoStatic
{
	private class InnerClass
	{
		/* All three static declarations raise the following compile error: non-static inner classes cannot have static declarations */
		static
		{
			System.out.println("= = = = = = = = = =");
		}
		private static int inProp;
		private static void test(a){}; }}Copy the code

A non-static inner class cannot have static methods, static member variables, or static initialization blocks.

Static inner class

An inner class that uses static decoration is called a static inner class;

Static inner classes can contain static or non-static members.

According to the rule that static members cannot access non-static members, a static inner class cannot access instance members of an external class, only class members of an external class. Even an instance method of a static inner class cannot access an instance member of an external class, only a static member of an external class.

public class TestStaticInnerClass
{
	private int prop1 = 5;
	private static int prop2 = 9;
	static class StaticInnerClass
	{
		private static int age;
		public void accessOuterProp(a)
		{
			A static inner class cannot access an instance member of an external class
			System.out.println(prop1);
			// The following code is normalSystem.out.println(prop2); }}}Copy the code

An outer class still cannot access members of a static inner class directly, but it can access class members of a static inner class using the class name of the static inner class as the caller. It can also access instance members of a static inner class using a static inner class object as the caller:

public class AccessStaticInnerClass
{
	static class StaticInnerClass
	{
		private static int prop1 = 5;
		private int prop2 = 9;
	}
	public void accessInnerProp(a)
	{
		//System.out.println(prop1);
		// There is an error in the above code, which should be changed to the following form: class members of static inner classes are accessed by class name
		System.out.println(StaticInnerClass.prop1);
		//System.out.println(prop2);
		// There is an error in the above code, which should be changed to look like this: instance members of static inner classes are accessed through instances
		System.out.println(newStaticInnerClass().prop2); }}Copy the code

Java allows you to define an inner class in an interface. By default, an inner class defined in an interface uses public static.

If you specify an access control for an interface inner class, you can specify only the public access control. If you omit the access control character when defining an interface inner class, the inner class defaults to public access control.

Using inner classes

1: Use an inner class inside an external class to create an instance with a new call to the inner class constructor;

The only difference is: do not use a non-static inner class in a static member of an external class (including static methods and static initialization blocks), because static members cannot access non-static members.

If you use a non-static inner class to access an inner class from a place other than the outer class (both static and non-static), the inner class cannot use private access control. If you use a private inner class to access an inner class, the inner class cannot use private access control. For inner classes that are modified by other access modifiers, they can be used within the corresponding access permission of the access control.

  • Inner classes that omit access control: can only be accessed by other classes in the same package as the outer class;
  • Protected inner classes: accessible by other classes in the same package as the outer class and by subclasses of the outer class;
  • Inner classes decorated with public: can be accessed anywhere;

When using an InnerClass outside of the OuterClass, the full class name of the InnerClass should be OuterClass.InnerClass;

Since an object of a non-static inner class must reside in an object of an external class, a non-static inner class object must be created before its external class object can be created. Syntax for creating an instance of a non-static inner class outside of an outer class:

OuterInstance.new InnerConstructor()
Copy the code
class Out
{
	// Define a non-static inner class that is accessible to other classes in the same package without access control
	class In
	{
		public In(String msg)
		{ System.out.println(msg); }}}public class CreateInnerInstance
{
	public static void main(String[] args) 
	{
		Out.In in = new Out().new In("Test message");
		/* the above code can be changed to the following three lines: define the InnerClass variable In the form outterclass.innerclass. Create an external class instance where a non-static inner class instance will be hosted. Out Out = new Out(); Create a non-static inner class instance by calling the inner class constructor with the outer class instance and new. In = out.new in (" test information "); * /}}Copy the code

Because a static inner class is related to an external class, there is no need to create an external class object when creating a static inner class object.

new OuterClass.InnerConstructor()
Copy the code
class StaticOut
{
	// Define a static inner class that is accessible to other classes in the same package without access control
	static class StaticIn
	{
		public StaticIn(a)
		{
			System.out.println("Constructors for static inner classes"); }}}public class CreateStaticInnerInstance
{
	public static void main(String[] args) 
	{
		StaticOut.StaticIn in = new StaticOut.StaticIn();
		/* the above code can be changed to the following two lines: define the InnerClass variable StaticOut.StaticIn in; Create a static inner class instance by calling the inner class constructor with new. In = new StaticOut.StaticIn(); * /}}Copy the code

Local inner class

Inner classes defined in methods are called local inner classes. Local inner classes also cannot be modified with access control and static modifiers;

public class LocalInnerClass
{
	public static void main(String[] args) 
	{
		// Define local inner classes
		class InnerBase
		{
			int a;
		}
		// Define a subclass of a local inner class
		class InnerSub extends InnerBase
		{
			int b;
		}
		// Create objects for local inner classes
		InnerSub is = new InnerSub();
		is.a = 5;
		is.b = 8;
		System.out.println("The a and B properties of the InnerSub object are:" + is.a + ","+ is.b); }}Copy the code

Anonymous inner class

Anonymous inner classes are good for creating classes that only need to be used once;

Anonymous inner classes must inherit a parent class or implement an interface, but only one parent class or implement one interface;

Anonymous inner classes have two rules:

  1. Anonymous inner classes cannot be abstract classes;
  2. Anonymous inner classes cannot define constructors. Anonymous inner classes cannot define constructors because they do not have class names, but anonymous inner classes can define initializer blocks, which can be instantiated to do what the constructor needs to do;
interface Product
{
	public double getPrice(a);
	public String getName(a);
}
public class TestAnonymous
{
	public void test(Product p)
	{
		System.out.println("Purchased one." + p.getName() + ", spent." + p.getPrice());
	}
	public static void main(String[] args) 
	{
		TestAnonymous ta = new TestAnonymous();
		// When we call the test method, we pass a Product argument, where we pass an instance of its anonymous implementation class
		ta.test(new Product()
		{
			public double getPrice(a)
			{
				return 567.8;
			}
			public String getName(a)
			{
				return "AGP card"; }}); }}Copy the code

The code above to create the Product implementation object can be broken down into the following code:

class AnonymousProduct implements Product
{
	public double getPrice(a)
	{
		return 567.8;
	}
	public String getName(a)
	{
		return "AGP card";
	}
}
ta.test(new AnonymousProduct());
Copy the code

When an anonymous inner class is created by inheriting from its parent class, the anonymous inner class will have a constructor similar to the parent class (with the same parameter list);

Before Java8, Java required that local variables accessed by local inner classes and anonymous inner classes be final. Starting with Java8, this restriction has been removed. Java8 is smarter: If a local variable is accessed by an anonymous inner class, it automatically uses the final modifier:

interface A
{
	void test(a);
}
public class TestA
{
	public static void main(String[] args) 
	{
		int age = 0;
		A a = new A()
		{
			public void test(a)
			{
				// before Java8, the following statement will prompt an error: age must be final
				// As of Java8, anonymous inner classes and local inner classes allow access to non-final local variablesSystem.out.println(age); }}; }}Copy the code

This time the notes can be really many, have to slowly digest it!! Books: Crazy Java handout