> 文章列表 > 2023.3.23

2023.3.23

2023.3.23

@16:继承

继承最大的好处就是:提高代码的复用性。

Person:属性:age,name,height -----> 这些属性都是private修饰的,被封装好的。

方法:eat( ),sleep()

Student:属性:sno

​ 方法:study( )

Student 继承自Person , 那么Student里面就有:age,name,height ,sno,eat( ),sleep(),study( )

注意:

1:父类中private修饰的属性,其实子类也是继承过来的,只是由于封装的特性,不可以在子类中直接的调用,但是可以通过setter getter接口间接调用。

2:一个父类可以有无数的子类,但是一个子类只能有一个直接父类,但是他可以间接的继承自其他的父类,比如说当其他的孙子类或是重孙子类。

3:所有的类都直接或者间接的继承自Object。

继承的内存分析:(下面连接)

https://blog.csdn.net/TYRA9/article/details/128729074?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167955107816782425164761%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=167955107816782425164761&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-128729074-null-null.142

在这里插入图片描述

还需要注意的是:父类中的static修饰的成员变量与成员方法也会被继承到子类中,但是不可以在子类中重写

这些方法,因此不能实现多态。

如果父类的属性被声明为 public 或 protected,那么子类可以继承这些属性,并且可以在子类中访问这些属性。如果父类的属性被声明为 private,那么子类也会继承这些属性,但由于封装的特性,子类无法直接调用。如果父类的属性没有被声明为任何访问限定符修饰符,即使用 default 修饰符,则同包的子类可以继承这些属性,但不同包的子类无法继承这些属性。

需要注意的是,如果父类的属性被声明为 final,那么子类无法覆盖这些属性(常量被放到常量池中),但是子类仍然可以继承这些属性。如果父类的属性被声明为 static,那么子类可以继承这些属性,可以通过子类的实例,子类类名,父类类名访问这些属性。

@17:protected关键字

protected关键字最大权限到不同包的子类。

在这里插入图片描述

类修饰符:public,default

方法/属性修饰符:public,protected,default,private

@18:方法的重写

方法的重写:发生在继承中,子类与父类之间,当子类对父类提供的方法不满意的时候,子类对父类提供的方法进行重写。

重载与重写的区别:

重载:发生在同一个类中,重载的方法的方法名相同,参数不同。

重写:子类与父类之间,当子类对父类提供的方法不满意的时候,子类对父类提供的方法进行重写。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOVJJz0S-1679579269434)(D:/%E4%BD%A0%E5%A5%BDJava/1007.png)]

注意:重写的返回值:当父类与子类的返回值都是基本数据类型的时候(比如说父类返回值类型是int,子类的返回值类型是double)是不可以的,当父类与子类的返回值类型是引用类型时,必须满足父类的返回值范围大于子类才行(比如说父类返回Person类型,子类返回Student类型,person是Student的父类,这样是可以的)。

内存图:

看这个图之前最好看一下继承中的内存分析

在这里插入图片描述

@19:super关键字

看这个之前最好看一下继承中的内存分析

public class M1 {int age = 10;String name = "000";double height = 199.2;public void eat() {}
}public class M2 extends M1{int oop = 100000;public void said() {this.age = 100;}public void see() {System.out.println(this.age); // 100System.out.println(super.age); // 100System.out.println(super.height);this.oop = 19;System.out.println(this.oop);}
}public class M3 extends M2{public void sleep() {this.age = 1000;System.out.println(this.age); // 1000System.out.println(super.age); // 1000System.out.println(this.oop);System.out.println(super.oop);this.see();}public static void main(String[] args) {M2 m2 = new M2();m2.said();m2.see();M3 m3 = new M3();m3.sleep();}
}
/*
100
100
199.2
19
1000
1000
100000
100000
1000
1000
199.2
19
*/

继承条件下构造方法的执行过程

在这里插入图片描述

用链表实现队列和栈的功能

package Novice_class;import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;// 单链表实现队列和栈
public class LinkedListToQueueAndStack {public static class Node<V> {public V value;Node<V> next;public Node(V value) {this.value = value;}}public static class MyQueue<V> {Node<V> head;Node<V> tail;int usedSized;public MyQueue() {head = null;tail = null;usedSized = 0;}public boolean isEmpty() {return this.usedSized == 0;}public int size() {return usedSized;}public void offer(V value) {Node<V> cur = new Node<>(value);if(head == null) {head = cur;tail = cur;}else {tail.next = cur;tail = cur;}tail.next = null;usedSized++;}public V poll() {if(this.isEmpty()) {return null;}V cur = head.value;head = head.next;if(head == null) {tail = null;}usedSized--;return cur;}public V peek() {return this.isEmpty() ? null : this.head.value;}}public static class MyStack<V> {Node<V> head;Node<V> tail;int usedSize;public MyStack() {this.head = null;this.tail = null;this.usedSize = 0;}public Boolean isEmpty() {return this.usedSize == 0;}public int size() {return this.usedSize;}public void push(V value) {Node<V> cur = new Node<>(value);if(head == null) {head = cur;tail = cur;}else {tail.next = cur;tail = cur;}tail.next = null;usedSize++;}public V pop() {if(head == null) {return null;}if(head == tail) {V value = this.head.value;head = null;tail = null;usedSize--;return value;}Node<V> cur = head;while(cur.next != tail) {cur = cur.next;}V value = this.tail.value;tail = cur;tail.next = null;usedSize--;return value;}public V peek() {return this.isEmpty() ? null : this.tail.value;}}public static void testStack() {MyStack<Integer> myStack = new MyStack<>();Stack<Integer> test = new Stack<>();int testTime = 5000000;int maxValue = 200000000;System.out.println("测试开始!");for (int i = 0; i < testTime; i++) {if (myStack.isEmpty() != test.isEmpty()) {System.out.println("isempty Oops!");}if (myStack.size() != test.size()) {System.out.println("size Oops!");}double decide = Math.random();if (decide < 0.33) {int num = (int) (Math.random() * maxValue);myStack.push(num);test.push(num);} else if (decide < 0.66) {if (!myStack.isEmpty()) {int num1 = myStack.pop();int num2 = test.pop();if (num1 != num2) {System.out.println("pop Oops!");}}} else {if (!myStack.isEmpty()) {int num1 = myStack.peek();int num2 = test.peek();if (num1 != num2) {System.out.println("isempty Oops!");}}}}if (myStack.size() != test.size()) {System.out.println("size Oops!");}while (!myStack.isEmpty()) {int num1 = myStack.pop();int num2 = test.pop();if (num1 != num2) {System.out.println("isempty Oops!");}}System.out.println("测试结束!");}public static void main(String[] args) {//testQueue();testStack();}
}