Inheritance and polymorphism
inherit
summary
origin
When the same attributes and behaviors exist in multiple classes, these contents are extracted into a single class, so multiple classes do not need to define these attributes and behaviors, just inherit that class. As shown in the figure:
Among them, multiple classes can be called subclasses, and the single class is called parent class, superclass or base class.
Inheritance describes the ownership relationship between things, which is the relationship of is-a. For example, rabbits in the picture belong to herbivores, and herbivores belong to animals. It can be seen that the parent class is more general and the child class is more specific. Through inheritance, we can form a relationship system between a variety of things.
definition
benefit
Inherited format
With the extends keyword, you can declare that a subclass inherits another parent class. The definition format is as follows:
class 父类 {
...
}
class 子类 extends 父类{
...
}
The inheritance demonstration code is as follows:
//定义员工类Employee作为父类
class Employee {
//定义name属性
String name;
//定义员工的工作方法
public void work() {
System.out.println("尽心尽力地工作");
}
}
//定义教师类Teacher继承员工类Employee
class Teacher extends Employee {
//定义一个打印name的方法
public void printName() {
System.out.println("name="+ name);
}
}
//定义测试类
public class ExtendDemo01 {
public static void main(String[] args) {
//创建一个教师类对象
Teacher t = new Teacher();
//为该员工类的name属性赋值
t.name = "小明";
//调用Teacher类中的printName()方法
t.printName(); // name=小明
//调用Teacher类继承来的Work()方法
t.work(); // 尽心尽力地工作
}
}
Inherited features - member variables
When there is a relationship between classes, what impact does the member variables in each class have?
Member variables do not have the same name
If a member variable with no duplicate name appears in the parent class of the child class, the access will not be affected. The code is as follows:
class Fu {
//Fu中的成员变量
int num = 5;
}
class Zi extends Fu {
//Zi中的成员变量
int num2 = 6;
//Zi中的成员方法
public void show() {
//访问父类中的num
System.out.println("Fu num = "+num); //继承而来,所以直接访问。
//访问子类中的num2
System.out.println("Zi num2 = "+num2);
}
}
class ExtendsDemo02 {
public static void main(String[] args) {
//创建子类对象
Zi z = new Zi();
//调用子类中的show()方法
z.show();
}
}
演示结果:
Fu num = 5
Zi num2 = 6
Duplicate member variable name
If a member variable with the same name appears in the parent class of the child class, the access will be affected. The code is as follows:
class Fu {
//Fu中的成员变量
int num = 5;
}
class Zi extends Fu {
//Zi中的成员变量
int num = 6;
//Zi中的成员方法
public void show() {
//访问父类中的num
System.out.println("Fu num = "+num);
//访问子类中的num
System.out.println("Zi num = "+num);
}
}
class ExtendsDemo02 {
public static void main(String[] args) {
//创建子类对象
Zi z = new Zi();
//调用子类中的show()方法
z.show();
}
}
演示结果:
Fu num = 6
Zi num = 6
When a member variable with the same name appears in the child parent class, you need to use the super keyword to modify the parent member variable when you need to access the non private member variable in the parent class in the child class, similar to this learned before.
Use format:
super.父类成员变量名
The subclass method needs to be modified, and the code is as follows:
class Zi extends Fu {
//Zi中的成员变量
int num = 6;
//Zi中的成员方法
public void show() {
//访问父类中的num
System.out.println("Fu num = "+super.num);
//访问子类中的num
System.out.println("Zi num = "+num);
}
}
演示结果:
Fu num = 5
Zi num = 5
Characteristics after inheritance -- member method
When there is a relationship between classes, what impact does the member methods in each class have?
The member method does not have the same name
If there is a member method with no duplicate name in the parent class of the child class, the call will not be affected. When an object calls a method, it will first find out whether there is a corresponding method in the subclass. If there is a method in the subclass, it will execute the method in the subclass. If there is no method in the subclass, it will execute the corresponding method in the parent class. The code is as follows:
class Fu {
public void show() {
System.out.println("Fu类中的show方法执行");
}
}
class Zi extends Fu {
public void show2() {
System.out.println("Zi类中的show2方法执行");
}
}
public class ExtendsDemo04 {
public static void main(String[] args) {
Zi z = new Zi();
//子类中没有show方法,但是可以找到父类方法去执行
z.show();
z.show2();
}
}
演示结果:
Fu类中的show方法执行
Zi类中的show2方法执行
Duplicate member method name -- override
If a member method with the same name appears in the parent class of a child class, the access is a special case, which is called method override.
The code is as follows:
class Fu {
public void show() {
System.out.println("Fu类中的show方法执行");
}
}
class Zi extends Fu {
public void show() {
System.out.println("Zi类中的show方法执行");
}
}
public class ExtendsDemo04 {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
演示结果:
Zi类中的show方法执行
Rewritten application
Subclasses can define their own behavior as needed. It not only follows the function name of the parent class, but also re implements the parent class method according to the needs of the child class, so as to expand and enhance.
matters needing attention
Characteristics after inheritance -- construction method
When there is a relationship between classes, what impact does the construction method in each class have?
First, we need to recall two things, the definition, format and function of construction methods.
Super and this
Parent class space takes precedence over child class objects
Each time a subclass object is created, the parent class space is initialized first, and then the subclass object itself is created. The purpose is that if the subclass object contains its corresponding parent class space, it can contain the members of its parent class. If the parent class member is not private decorated, the subclass can use the parent class member at will. The code is reflected in that when the constructor of a subclass is called, the constructor of the parent class must be called first. The understanding diagram is as follows:
Meaning of super and this
Usage of super and this
Characteristics of inheritance
abstract class
summary
origin
The method in the parent class is overridden by its subclasses, and the implementation of subclasses is different. Then the method declaration and method body of the parent class, only the declaration has meaning, while the method body has no meaning. We call methods without method bodies abstract methods. Java syntax stipulates that a class containing abstract methods is an abstract class.
definition
Abstract use format
Abstract method
Using the abstract keyword to modify a method, the method becomes an abstract method. The abstract method contains only a method name and no method body.
Define format:
修饰符 abstract 返回值类型 方法名 (参数列表);
Code example:
public abstract void run();
abstract class
If a class contains abstract methods, the class must be abstract.
Define format:
abstract class 类名字 {
}
Code example:
public abstract class Animal {
public abstract void run();
}
Use of abstraction
Subclasses that inherit abstract classes must override all abstract methods of the parent class. Otherwise, the subclass must also be declared as an abstract class. Finally, a subclass must implement the abstract method of the parent class. Otherwise, objects cannot be created from the original parent class to the final subclass, which is meaningless.
Code example:
public class Cat extends Animal {
public void run() {
System.out.println("小猫在墙头走");
}
}
public class CatTest {
public static void main(String[] args) {
Cat c = new Cat();
c.run();
}
}
输出结果:
小猫在墙头走
The method rewriting at this time is the completion and implementation of the parent class's abstract method by the subclass. The operation of rewriting this method is also called the implementation method.
matters needing attention
As for the use of abstract classes, the following are the details that should be paid attention to in syntax. Although there are many items, if you understand the essence of abstraction, you don't need to memorize by rote.
1. An abstract class cannot create an object. If it is created, the compilation fails and an error is reported. Only objects whose non Abstract subclasses can be created.
2. There can be construction methods in abstract classes, which are used to initialize parent class members when subclasses create objects.
3. Abstract classes do not necessarily contain abstract methods, but classes with abstract methods must be abstract classes.
4. The subclass of an abstract class must override all the abstract methods in the abstract parent class. Otherwise, the compilation fails and an error is reported. Unless the G subclass is also an abstract class.
Comprehensive case of inheritance
The group leader sends ordinary red envelopes. There are several members in a group. The group leader sends ordinary red envelopes to the members. Rules for ordinary red envelopes:
Please complete the definition of all classes in the case and the inheritance relationship between the specified classes according to the description, and complete the operation of sending red envelopes.
According to the description and analysis, the following inheritance system is obtained
Case realization
Define user classes:
public class User {
private String username; //用户名
private double leftMoney; //余额
//构造方法
public User(){}
public User(String username,double leftMoney) {
this.username = username;
this.leftMoney = leftMoney;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getLeftMoney() {
return leftMoney;
}
public void setLeftMoney(double leftMoney) {
this.leftMoney = leftMoney;
}
public void show() {
System.out.println("用户名:"+ username + ",余额为:" + leftMoney + "元");
}
}
Define group main class:
public class Qunzhu extends User {
public Qunzhu(){}
public Qunzhu(String username,double leftMoney) {
super(username,leftMoney);
}
/*
群主发红包,就是把一个浮点数的金额分成若干份。
1.获取群主金额,是否够发红包 不够则返回null并提示 够则继续
2.修改群主余额
3.拆分红包
3.1 如果能被整除就平均分
3.2 如果不能 那么就把余数分给最后一份
*/
public ArrayList<Double> send(double money,int count) {
double leftMoney = getLeftMoney();
if (money > leftMoney) {
return null;
}
//修改群主余额
setLeftMoney(leftMoney - money);
//创建一个集合,保存等份金额
ArrayList<Double> list = new ArrayList<>();
//扩大100倍,相当于折算成‘分’为单位,避免小数运算损失精度
money = money * 100;
//每份的金额
double m = money / count;
//不能整除的余数
double l = money % count;
for(int i = 0;i < count - 1; i++) {
list.add(m / 100.0);
}
if(l == 0) {
//能整除,最后一份金额与之前每份金额一致
list.add(m / 100.0);
} else {
//不能整除,最后一份金额为之前每份的金额+余数金额
list.add((m + 1) / 100.0);
}
return list;
}
}
Define member classes:
public class Member extends User{
public Member() {}
public Member(String username,leftMoney);
}
// 打开红包,就是从集合中随机取出一份保存到自己的余额中
public void openHongbao(ArrayList<Double> list) {
Random r = new Random();
int index = r.nextInt(list.size());
Double money = list.remove(index);
setLeftMoney(money);
}
}
Test class:
public class Test {
public static void main(String[] args) {
Qunzhu qz = new Qunzhu("群主",200);
Scanner sc = new Scanner(system.in);
System.out.println("请输入金额:");
double money = sc.nextDouble();
System.out.println("请输入个数:");
int count = sc.nextInt();
//发送红包
ArrayList<Double> sendList = qz.send(money,count);
if(sendList == null) {
System.out.println("余额不足...");
return;
}
Member m1 = new Member();
Member m2 = new Member();
Member m3 = new Member();
m1.openHongbao(sendList);
m2.openHongbao(sendList);
m3.openHongbao(sendList);
qz.show();
m1.show();
m2.show();
m3.show();
}
}
Interface
summary
Interface is a reference type in the Java language and a collection of methods. If a class encapsulates member variables, construction methods and member methods, the interior of the interface mainly encapsulates methods, including abstract methods (JDK 7 and before), default methods and static methods (JDK 8) and private methods (JDK 9).
Interface, which is similar to defining classes, but uses the interface keyword. It will also be compiled into Class file, but it must be clear that it is not a class, but another reference data type.
For the use of an interface, it cannot create objects, but can be implemented (similar to inherited). A class that implements an interface (which can be regarded as a subclass of the interface) needs to implement all the abstract methods in the interface. If you create this class object, you can call the method, otherwise it must be an abstract class.
Define format
public interface 接口名称 {
//抽象方法
//默认方法
//静态方法
//私有方法
}
Contains abstract methods
Abstract method: use the abstract keyword to modify. It can be omitted. There is no method body. This method is used by subclass implementations.
The code is as follows:
public interface InterFaceName {
public abstract void method();
}
Contains default and static methods
Default method: use the default modifier and cannot be omitted. It can be called or overridden by subclasses.
Static method: static modification is used for the interface to call directly.
The code is as follows:
public interface InterFaceName {
public default void method() {
//执行语句
}
public static void method2() {
//执行语句
}
}
Contains private methods and private static methods
Private method: private modification is used for calling the default method or static method in the interface.
The code is as follows:
public interface InterFaceName {
private void method() {
//执行语句
}
}
Basic implementation
Overview of implementation
The relationship between class and interface is implementation relationship, that is, class implements interface. This class can be called implementation class of interface or subclass of interface. The implemented actions are similar to inheritance and the format is similar, but the keywords are different. The implementation uses the implements keyword.
Non Abstract subclass implementation interface:
Implementation format:
class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}
Use of abstract methods
All must be implemented, and the code is as follows:
Define interface:
public interface LivaAble {
//定义抽象方法
public abstract void eat();
public abstract void sleep();
}
Define implementation classes:
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void sleep() {
System.out.println("晚上睡");
}
}
Test class:
public class InterfaceDemo {
public static void main(String[] args) {
//创建子类对象
Animal a = new Animal();
//调用实现后的方法
a.eat();
a.sleep();
}
}
输出结果:
吃东西
晚上睡
Use of default methods
You can inherit, override, or choose one, but you can only call it through the object that implements the class.
1. The default inheritance method is as follows:
Define interface:
public interface LiveAble {
public default void fly() {
System.out.println("天上飞");
}
}
Define implementation classes:
public class Animal implements LiveAble {
//继承,什么都不用谢,直接调用
}
Test class:
public class InterfaceDemo {
public static void main(String[] args) {
//创建子类对象
Animal a = new Animal();
//调用默认方法
a.fly();
}
}
输出结果:
天上飞
2. Override the default method with the following code:
Define interface:
public interface LiveAble {
public default void fly() {
System.out.println("天上飞");
}
}
Define implementation classes:
public class Animal implements LiveAble {
@Override
public void fly() {
System.out.println("自由自在的飞");
}
}
Test class:
public class InterfaceDemo {
public static void main(String[] args) {
//创建子类对象
Animal a = new Animal();
//调用重写方法
a.fly();
}
}
输出结果:
自由自在的飞
Use of static methods
Static vs Class files are related, and can only be called by the interface name, not by the class name of the implementation class or the object of the implementation class. The code is as follows:
Define interface:
public interface LiveAble {
public static void run() {
System.out.println("地上跑");
}
}
Define implementation classes:
public class Animale implements LiveAble {
//无法重写静态方法
}
Test class:
public class InterfaceDemo {
public static void main(String[] args) {
// Animal.run(); //【错误】无法继承方法,也无法调用
LiveAble.run();
}
}
输出结果:
地上跑
Use of private methods
If there are multiple default methods in an interface and there are duplicate contents in the methods, they can be extracted and encapsulated into private methods for the default methods to call. From a design perspective, private methods are an aid to default and static methods.
Define interface:
public interface LiveAble {
default void func() {
func1();
func2();
}
private void func1(){
System.out.println("func1~~");
}
private void func2(){
System.out.println("func2~~");
}
}
Multiple implementation of interface
I learned before that in the inheritance system, a class can only inherit one parent class. For interfaces, a class can implement multiple interfaces, which is called multiple implementation of interfaces. Moreover, a class can inherit a parent class and implement multiple interfaces at the same time.
Implementation format:
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
//重写接口中的抽象方法【必须】
//重写接口中的默认方法【不重名时可选】
}
Abstract method
When there are multiple abstract methods in the interface, the implementation class must override all abstract methods. If the abstract method has duplicate names, it only needs to be rewritten once. The code is as follows:
Define multiple interfaces:
interface A {
public abstract void showA();
public abstract void show();
}
interface B {
public abstract void showB();
public abstract void show();
}
Define implementation classes:
public class C implements A,B{
@Override
public void showA() {
System.out.println("showA");
}
@Override
public void showB() {
System.out.println("showB");
}
@Override
public void show() {
System.out.println("show");
}
}
Default method
When there are multiple default methods in the interface, the implementation class can inherit and use them. If the default method has duplicate names, it must be overridden once. The code is as follows:
Define multiple interfaces:
interface A {
public default void methodA(){}
public default void method(){}
}
interface B {
public default void methodB(){}
public default void method(){}
}
Define implementation classes:
public class C implements A,B {
@Override
public void method() {
System.out.println("method");
}
}
Static method
Static methods with the same name in the interface will not conflict because they can only be accessed through their respective interface names.
Priority issues
When a class inherits a parent class and implements several interfaces, the member method in the parent class has the same name as the default method in the interface, and the subclass selects the member method of the parent class nearby. The code is as follows:
Define interface:
interface A {
public default void methodA(){
System.out.println("AAA");
}
}
Define parent class:
class B {
public void methodA(){
System.out.println("BBB");
}
}
Define subclasses:
class C extends D implements A {
//未重写methodA方法
}
Test class:
public class Test {
public static void main(String[] args) {
C c = new C();
c.methodA();
}
}
输出结果:
BBB
Interface multi inheritance [understand]
One interface can inherit another or more interfaces, which is similar to inheritance between classes. Interface inheritance uses the extends keyword, and the child interface inherits the methods of the parent interface. If the default method in the parent interface has duplicate names, the child interface needs to be rewritten once. The code is as follows:
Define parent interface:
interface A {
public default void method(){
System.out.println("AAA");
}
}
interface B {
public default void method(){
System.out.println("BBB");
}
}
Define sub interfaces:
interface D extends A,B {
@Override
public default void method() {
System.out.println("DD");
}
}
Characteristics of other members
polymorphic
summary
introduce
Polymorphism is the third feature of object-oriented after encapsulation and inheritance.
In life, such as running, kittens, dogs and elephants run differently. Another example is the action of flying. Insects, birds and planes fly differently. It can be seen that the same behavior can reflect different forms through different things. Polymorphism describes such a state.
definition
Premise [key]
Embodiment of polymorphism
Format of polymorphism:
父类类型 变量名 = new 子类对象;
变量名.方法名();
The code is as follows:
Fu f = new Zi();
f.method();
When calling a method in a polymorphic way, first check whether the method exists in the parent class. If not, the compilation error will occur; If so, the subclass overridden method is executed.
The code is as follows:
Define parent class:
public abstract class Animal {
public abstract void eat();
}
Define subclasses:
public Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
}
public Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
}
Test class:
public class Test {
public static void main(String[] args) {
//多态形式,创建对象
Animal a1 = new Cat();
//调用的是Cat的eat
a1.eat();
//多态形式,创建对象
Animal a2 = new Dog();
//调用的是Dog的eat
a2.eat();
}
}
输出结果:
吃鱼
吃骨头
Benefits of polymorphism
In the actual development process, the parent class type is used as the formal parameter of the method, passing the subclass object to the method and calling the method, which can better reflect the expansibility and convenience of polymorphism. The code is as follows:
Define parent class:
public abstract class Animal {
public abstract void eat();
}
Define subclasses:
public Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
}
public Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
}
Test class:
public class Test_1 {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
showCatEat(c);
showDogEat(d);
/*
以上两个方法均可以被showAnimalEat(Animal a)方法所替代,且执行效果一致
*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat(Cat c){
c.eat();
}
public static void showDogEat(Dog d){
d.eat();
}
public static void showAnimalEat(Animal a){
a.eat();
}
}
Due to the support of polymorphism, the animal type of showanimaleat method is the parent type of cat and dog. The parent type receives child objects. Of course, cat objects and dog objects can be passed to the method.
When the eat method is executed, the polymorphism stipulates that it is a subclass overriding method. The effect is naturally consistent with the showcateat and showdogeat methods, so showanimaleat can completely replace the above two methods.
Not only substitution, but also extensibility. No matter how many subclasses appear later, we don't need to write showxxeat method. We can use showanimaleat directly.
Therefore, the benefits of polymorphism are that it can make the programming simpler and have good expansion.
Reference type conversion
Polymorphic transformation can be divided into upward transformation and downward Transformation:
Upward transformation
When the parent class reference points to a subclass object, it is an upward transformation.
Use format:
父类类型 变量名 = new 子类类型();
如 Animal a = new Cat();
Downward transformation
For a subclass object that has been transformed upward, the parent class reference can be transformed into a subclass reference. The format of forced type conversion can be used, that is, downward transformation.
Use format:
子类类型 变量名 = (子类类型) 父类变量名;
如 Cat c = (Cat) a;
Why transformation
When calling a method in a polymorphic way, first check whether the method exists in the parent class. If not, the compilation error will occur. That is, you cannot call methods owned by a child class but not by a parent class. Compilation errors, let alone running. This is also a little "little trouble" brought to us by polymorphism. Therefore, if you want to call subclass specific methods, you must make a downward transformation.
Transformation demonstration, the code is as follows:
Define class:
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void catchMouse() {
Sysetm.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void watchHouse() {
System.out.println("看家");
}
}
Test class:
public class Test {
public static void main(String[] args) {
//向上转型
Animal a = new Cat();
a.eat(); //调用的是Cat的eat
//向下转型
Cat c = (Cat) a;
c.catchMouse();
}
}
Abnormal transformation
In the process of transformation, you will encounter such problems accidentally. Please see the following code:
public class Test {
public static void main(String[] args) {
//向上转型
Animal a = new Cat();
a.eat();
//向下转型
Dog d = (Dog)a;
d.watchHouse(); //调用的是Dog的watchHouse 【运行报错】
}
}
This code can be compiled, but ClassCastException and type conversion exception are reported at runtime! This is because cat type objects are clearly created. Of course, they cannot be converted into dog objects at run time. These two types do not have any inheritance relationship and do not conform to the definition of type conversion.
In order to avoid ClassCastException, Java provides the instanceof keyword to verify the type of reference variables. The format is as follows:
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
Therefore, before conversion, let's make a judgment. The code is as follows:
public class Test {
public static void main(String[] args) {
//向上转型
Animal a = new Cat();
a.eat();
//向下转型
if (a instanceof Cat) {
Cat c = (Cat) a;
c.catchMouse();
} else if (a instanceof Dog) {
Dog d = (Dog)a;
d.watchHouse();
}
}
}
Comprehensive case of interface polymorphism
Laptops usually have the function of using USB devices. During production, laptops have reserved USB interfaces that can be inserted into USB devices, but the notebook manufacturers do not care about the specific USB devices, as long as they meet the USB specifications.
Define USB interface, with basic on and off functions. In order to use the mouse and keyboard on the computer, the mouse and keyboard must also comply with the USB specification and realize the USB interface, otherwise the mouse and keyboard cannot be used.
case analysis
Describe the notebook class to realize that the notebook uses USB mouse and USB keyboard
Case realization
Define USB interface:
public interface USB {
void open(); //开启功能
void close(); //关闭功能
}
Define mouse class:
public class Mouse implements USB {
@Override
public void open() {
System.out.println("鼠标开启,红灯亮");
}
@Override
public void close() {
System.out.println("鼠标关闭,红灯灭");
}
public void click() {
System.out.println("鼠标点击");
}
}
Define keyboard class:
public class KeyBoard implements USB {
@Override
public void open() {
System.out.println("键盘开启,绿灯亮");
}
@Override
public void close() {
System.out.println("键盘关闭,绿灯灭");
}
public void type() {
System.out.println("键盘打字");
}
}
Define notebook class:
class Laptop {
public void run() {
System.out.println("笔记本运行");
}
//笔记本使用usb设备,当笔记本对象调用这个功能时必须给其传递一个符合USB规则的USB设备
public void useUSB(USB usb) {
if (usb != null) {
usb.open();
if (usb instanceof Mouse){
Mouse m = (Mouse) usb;
m.click();
} else if (usb instanceof KeyBoard) {
KeyBoard kb = (KeyBoard)usb;
kb.type();
}
usb.close();
}
}
public void shutDown() {
System.out.println("笔记本关闭");
}
}
Test class:
public class Test {
public static void main(String[] args) {
Laptop lt = new Laptop();
lt.run();
//创建鼠标实体对象
USB u = new Mouse();
//笔记本使用鼠标
lt.useUSB(u);
//创建键盘实体对象
USB kb = new KeyBoard();
//笔记本使用键盘
lt.useUSB(kb);
lt.shutDown();
}
}
Final keyword
summary
After learning inheritance, we know that subclasses can rewrite the contents of the parent class based on the parent class, for example, method rewriting. So can we arbitrarily inherit the classes provided in the API and rewrite their contents? Obviously, this is inappropriate. In order to avoid this random rewriting, Java provides the final keyword to modify the unchangeable content.
Mode of use
Modifier class
The format is as follows:
final class 类名 {
}
The query API found that many of the classes we have learned, such as public final class string, public final class math, and public final class scanner, are modified by "nal" so that we can use them instead of changing their contents.
Modification method
The format is as follows:
修饰符 final 返回值类型 方法名(参数列表) {
//方法体
}
If you rewrite the method modified by final, an error will be reported during compilation.
Modifier variable
1. Local variables - basic types
After being modified by "nal", a local variable of basic type can only be assigned once and cannot be changed again.
2. Local variable - reference type
A local variable of reference type, modified by "nal", can only point to one object, and the address cannot be changed. However, it does not affect the modification of member variable values inside the object. The code is as follows:
public class FinalDemo2 {
public static void main(String[] args) {
//创建User对象
final User u = new User();
//创建另一个User对象
u = new User(); //报错,指向了新的对象,地址值改变。
//调用setName方法
u.setName("张三"); //可以修改
}
}
3. Member variables
Member variables involve initialization. There are two initialization methods, one of which can only be selected:
Permission modifier
summary
Four kinds of access rights are provided in Java. When modified with different access rights modifiers, the modified content will have different access rights.
Access capabilities with different permissions
It can be seen that public has the maximum permission. Private is the minimum permission.
When writing code, if there is no special consideration, it is recommended to use permissions as follows:
Inner class
summary
What is an inner class
Define a Class A in another class B, which class A is called the inner class and B is called the outer class.
Member inner class
Define format:
class 外部类 {
class 内部类 {
}
}
When describing things, if there are other things inside a thing, you can use the structure of inner class. For example, an automobile car contains an engine class. In this case, the engine can be described by an internal class and defined in the member position.
Code example:
class Car { //外部类
class Engine { //内部类
}
}
Access characteristics
Create internal class object format:
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
The access demo code is as follows:
Define class:
public class Person {
private boolean live = true;
class Heart {
public void jump() {
//直接访问外部类成员
if (live) {
System.out.println("心脏在跳动");
} else {
Sysetm.out.println("心脏不跳了");
}
}
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
}
Test class:
public class InnerDemo {
public static void main(String[] args) {
//创建外部类对象
Person p = new Person();
//创建内部类对象
Heart heart = p.new Heart();
//调用内部类方法
heart.jump();
//调用外部类方法
p.setLive(false);
//调用内部类方法
heart.jump;
}
}
输出结果:
心脏在跳动
心脏不跳了
Anonymous internal class [key]
Our goal is ultimately to call methods. Can we simplify the above four steps into one step? Anonymous inner classes are such shortcuts.
premise
Anonymous inner classes must inherit a parent class or implement a parent interface.
format
new 父类名或者接口名() {
//方法重写
@Override
public void method() {
//执行语句
}
};
Mode of use
Taking the interface as an example, the code of anonymous inner class is as follows:
Define interface:
public abstract class FlyAble{
public abstract void fly();
}
Create an anonymous inner class and call:
public class InnerDemo {
public static void main(String[] args) {
/*
1.等号右边:是匿名内部类,定义并创建该接口的子类对象
2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble() {
public void fly() {
System.out.println("fly~");
}
};
//调用fly方法,执行重写后的方法
f.fly();
}
}
Usually, when the formal parameter of a method is an interface or abstract class, you can also pass an anonymous inner class as a parameter. The code is as follows:
public class InnerDemo2 {
public static void main(String[] args) {
/*
1.等号右边:定义并创建该接口的子类对象
2.等号左边:是多态,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble() {
public void fly() {
System.out.println("fly~~");
}
};
//将f传递给showFly方法中
showFly(f);
}
public static void showFly(FlyAble f) {
f.fly();
}
}
The above two steps can also be simplified to one step. The code is as follows:
public class InnerDemo3 {
public static void main(String[] args) {
/*
创建匿名内部类,直接传递给showFly(FlyAble f)
*/
showFly(new FlyAble(){
public void fly() {
System.out.println("fly~~");
}
});
}
public static void showFly(FlyAble f) {
f.fly();
}
}
Reference type Usage Summary
In actual development, the use of reference types is very important and common. We can further master the use of reference types on the basis of understanding the use of basic types. A basic type can be used as a member variable, as a parameter of a method, and as a return value of a method. Of course, a reference type can also be used.
Class as a member variable
When defining a class role (game character), the code is as follows:
class Role {
int id; //角色id
int blood; //生命值
String name; //角色名称
}
The int type is used to represent the role ID and life value, and the string type is used to represent the name. At this time, string itself is a reference type. Because it is used in a similar way to a constant, it is often ignored that it is a reference type. If we continue to enrich the definition of this class and add weapons, wearable equipment and other attributes to role, how will we write it?
Defining weapons will increase attack capability:
class Weapon {
String name; //武器名称
int hurt; //伤害值
}
Defining wearing helmets and armor will increase defense ability, that is, increase HP:
class Armour {
String name; //装备名称
int protect; //防御值
}
Define role classes:
class Role {
int id;
int blood;
String name;
//添加武器属性
Weapon wp;
//添加盔甲属性
Armour ar;
//提供get/set方法
public Weapon getWp() {
return wp;
}
public void setWeapon(Weapon wp) {
this.wp = wp;
}
public Armour getArmour() {
return ar;
}
public void setArmour(Armour ar) {
this.ar = ar;
}
//攻击方法
public void attack() {
System.out.println("使用"+wp.getName() + ",造成"+wp.getHurt()+"点伤害");
}
//穿戴盔甲
public void wear() {
//增加防御就是增加blood值
this.blood += ar.getProtect();
System.out.println("穿上"+ar.getName()+",生命值增加"+ar.getProtect());
}
}
Test class:
public class Test {
public static void main(String[] args) {
//创建Weapon对象
Weapon wp = new Weapon("屠龙宝刀",99999);
//创建Armour对象
Armour ar = new Armour("麒麟甲",10000);
//创建Role对象
Role r = new Role();
//设置属性
r.setWeapon(wp);
r.setArmour(ar);
r.attack();
r.wear();
}
}
输出结果:
使用屠龙宝刀,造成99999点伤害
穿上麒麟甲,生命值增加10000
Interface as a member variable
Interface is the encapsulation of methods, corresponding to the game, which can be regarded as the skill of expanding game characters. Therefore, if we want to expand more powerful skills, we can add an interface as a member variable in role to set different skills.
Define interface:
//法术攻击
public interface FaShuSkill {
public abstract void FaShuAttack();
}
Define role classes:
public class Role {
FaShuSkill fs;
public void setFaShuSkill(FaShuSkill fs) {
this.fs = fs;
}
//法术攻击
public void FaShuSkillAttack() {
System.out.print("发动法术攻击:");
fa.FaShuAttack();
System.out.println("攻击完毕");
}
}
Test class:
public class Test {
public static void main(String[] args) {
//创建游戏角色
Role role = new Role();
//设置角色法术技能
role.setFaShuSkill(new FaShuSkill(){
@Override
public void FaShuAttack() {
System.out.println("纵横天下");
}
});
//发动法术攻击
role.FaShuSkillAttack();
//更换技能
role.setFaShuSkill(new FaShuSkill() {
@Override
public void FaShuAttack() {
System.out.println("逆转乾坤");
}
});
//发动法术攻击
role.FaShuSkillAttack();
}
}
输出结果:
发动法术攻击:纵横天下
攻击完毕
发动法术攻击:逆转乾坤
攻击完毕
Interface as method parameter and return value type
When an interface is used as a parameter of a method, what needs to be passed? When an interface is used as the return value type of a method, what needs to be returned? Yes, they are all subclass objects. The ArrayList class is not new to us. Looking at the API, we find that it is actually Java util. Implementation class of the list interface. Therefore, when we see the list interface as a parameter or return value type, we can certainly pass or return the ArrayList object.
Observe the following method: get all even numbers in a set.
Definition method:
public static List<Integer> getEvenNum(List<Integer> list){
//创建保存偶数的集合
ArrayList<Integer> evenList = new ArrayList<>();
for (int i = 0; i < list.size(); i++){
Integer integer = list.get(i);
if(integer % 2 == 0) {
evenList.add(integer);
}
}
/*
返回偶数集合
因为getEvenNum方法的返回值类型是List,而ArrayList是List的子类,所以evenList可以返回
*/
return evenList;
}
Call method:
public static void main(String[] args) {
//创建ArrayList集合,并添加数字
ArrayList<Integer> srcList = new ArrayList<>();
for(int i = 0; i < 10; i++) {
srcList.add(i);
}
/*
获取偶数集合
因为getEvenNum方法的参数是List,而ArrayList是List的子类,
所以srcList可以传递
*/
List list = getEvenNum(srcList);
System.out.println(list);
}