20220726 第一组 于芮 面相对象完结篇(第十八天)
代码块(初始化块)---类的一个成员
将逻辑语句封装在方法体中,通过{}包裹起来,代码块没有方法名,没有参数,没有返回值,只有方法体
不需要通过对象或者类进行显式的调用,会在类加载或创建对象时,主动的隐式调用。
静态代码块:static{}一个类被加载时会被调用一次,做一些初始化的工作,一个类里可以有多个静态块
实例代码块:{}每次创建实例,都会被调用依一次
类的内部结构(属性,方法,构造器,代码块,内部类)
当没有继承关系时----静态块--实力块---构造器
当有继承关系时,父类静态块---父类实力块---父类构造器——子类静态块---子类实力块---子类构造器
父类优于子类,静态块优于其他
静态static(修饰属性,方法,代码块)
不属于任何一个对象
static内存解析
1.静态的变量或方法存在于方法区,静态的结构不会被回收
2.静态声明的结构不属于任何一个实例对象,只存在于方法区,调用静态结构,直接用类名.属性名的方法
实例方法和静态方法的互相调用
1.静态方法不能直接调用实例方法
2.实例方法可以直接调用静态方法
静态结构的加载,随着类的加载而加载
非静态结构的加载,随着对象的创建而加载
在java中调用实例方法,必须有方法体,方法不是一等公民,不能直接调用。
静态方法无论在哪都是类名.方法名调用,同一个类的静态方法之间可以省略类名
静态方法没有重写
外部类:public声明的类必须和.java的文件名相同
内部类:在一个类中进行其他类的嵌套操作
实力内部类:
// 这就是实例内部类的对象
Inner inner = new Ch01().new Inner();
静态内部类:
// 静态内部类的对象
InnerStatic innerStatic = new Ch01.InnerStatic();
设计模式:人们为软件开发中抽象出可重复利用的解决方案
1.单例模式(一个类只有一个实例)
懒汉式(延迟加载)
private Ch04(){
}
public static Ch04 getInstance() {
if(ch04 == null){
// xcxxxxx
ch04 = new Ch04();
}
return ch04;
}
}
饿汉式:不管以后会不会使用到该实例化对象,先创建了再说,很着急的样子。
* 实现的办法就是直接new实例化。
public class Ch03 {
private static final Ch03 ch03 = new Ch03();
private Ch03(){}
public static Ch03 getInstance(){
return ch03;
}
}
面向对象的设计原则
1.开闭原则(对扩展开放,对修改关闭---继承,实现接口)
通过抽象约束,封装变化来实现开闭原则,通过接口或者抽象类为软件定义一个相对稳定的抽象层,
将相同的的可变因素封装在相同的具体实现类中,派生一个实体类就可以了
2.里氏代换原则
子类继承父类时,除了添加新的方法完成新增功能外,尽量不要重写父类方法
3.依赖倒转原则
要面向接口编程,尽量不要面向实现编程
A.每个类尽量提供接口或抽象类,或者两者兼备
B.变量的声明尽量是接口或者是抽象类
C.任何类都不应该从具体类派生
D.使用继承时要遵循里氏代换原则
4.接口隔离原则
使用多个隔离接口
5.迪米特法则
6.合成复用原则
7.单一原则(一个类只做一个事)
箭头函数(JDK8新特性)
函数式接口(注解--@functionalInterface):如果一个接口只有一个抽象方法,这个接口叫做函数式接口
1、有参数,有返回值。
* (i,j) -> {
* return i + j;
* }
* 如果方法体只是一句返回值(i,j) -> i+j
* 2、有参数,无返回值
* (i,j) -> {
* // 方法体
* }
* 如果方法体只有一句话(i,j) -> 方法体的一句话
* 3、无参数
* ()->{
* 方法体
* }
今天的实践任务是双链表,前几天学习了单链表,有异曲同工之妙,但是还需要多加理解的,看一下代码吧!
1 public class Doublelink { 2 class Node{ 3 //数据本身 4 Integer data; 5 //上一个节点地址 6 Node prev; 7 //下一个节点的地址 8 Node next; 9 10 public Node(Integer data) { 11 this.data = data; 12 } 13 14 public Node() { 15 } 16 17 @Override 18 public String toString() { 19 return "Node{" + 20 "data=" + data + 21 ", prev=" + prev + 22 ", next=" + next + 23 '}'; 24 } 25 //维护一个头结点,头结点不要动,不存放具体的数据 26 private Node head=new Node(0); 27 //返回头结点 28 public Node getHead(){ 29 return head; 30 } 31 //显示链表(遍历) 32 33 public void list(){ 34 if(head.next==null){ 35 System.out.println("链表为空……"); 36 return; 37 } 38 //因为头结点,不能动,我们需要一个辅助变量帮助遍历 39 Node temp=head.next; 40 while(true){ 41 //判断是否走到最后 42 if(temp==null){ 43 break; 44 } 45 System.out.println(temp.data); 46 //将指针后移 47 temp=temp.next; 48 } 49 } 50 //添加节点到链表的最后 51 //默认添加的是到链表的最后一个位置 52 //找到链表的最后一个节点 53 //把这个节点的下一个指向当前节点 54 //当前节点的上一个节点指向之前的最后一个节点 55 public void add(Node node) { 56 //因为我们头结点不能动,我们 57 Node temp=head; 58 while(true){ 59 //找到链表的表尾节点 60 if(temp.next==null){ 61 break; 62 } 63 //如果没有找到最后,将temp后移 64 temp=temp.next; 65 } 66 //当退出while循环时,temp指针就指向了最后 67 temp.next=node; 68 node.prev=temp; 69 } 70 public void main(String[] args) { 71 Doublelink doublelink=new Doublelink(); 72 doublelink.add(new Node(1)); 73 doublelink.add(new Node(2)); 74 doublelink.add(new Node(3)); 75 doublelink.add(new Node(4)); 76 doublelink.list(); 77 } 78 } 79 80 81 }