JAVA基础学习

第二篇文章的连接: (超详细笔记整理)动力节点_老杜 | JavaSE进阶 【P486之后】.

文章目录

  • JAVA基础学习
    • 方法
      • Java的主要内存空间
      • 栈数据结构
        • **栈数据结构:stack**
      • 方法区执行时内存的变换
      • 方法总结
      • 方法的重载
      • 方法递归
        • **递归求阶乘**
    • 认识面向对象
      • 1. 面向过程和面向对象有什么区别?
      • 2. 当我们采用面向对象的方式贯穿整个系统的时候,涉及到三个术语:
      • 3. 面向对象的三大特征
      • 4. 类和对象的概念
        • 什么是类?
        • 什么是对象?(真实存在个体)
          • **类 ——[实例化] ——> 对象(实例)**
          • **对象 ——[抽象] ——> 类**
        • 类的共同特征
      • 5. java软件工程师在开发中起到的作用是什么?
      • 6. 类的定义
        • 怎么定义一个类,语法格式是什么?
        • 为什么属性以“变量”的形式存在?
      • 7. 编译的过程
    • 对象的创建与使用
        • 对象的创建
      • 什么是实例变量
        • 实例变量在访问的时候,是不是必须先创建对象?
      • 对象和引用的区别?
      • JVM中的三个主要内存
      • 属性的引用
      • 空指针
      • 方法调用时的参数传递
      • 构造方法Constructor
        • 1.什么是构造方法?有什么用?
        • 2.当一个类没有提供任何构造方法,但是系统实际上会默认提供一个无参数的构造方法,(这个方法会被称为缺省构造器)
        • 3.调用构造方法如何使用呢?
        • 4.构造方法的语法结构是什么?
        • 5.无参数的构造方法和有参数的构造方法
      • 调用不同构造方法创造对象
    • 面向对象的三大特征-封装、继承、多态
      • 封装
        • 什么是封装?有什么用?
        • **封装的作用**:
        • 怎么进行封装
    • static关键字
        • **静态变量在类加载时进行初始化**
        • 1.**当county不是静态变量的时候:会导致内存的浪费,country放在堆中**
        • 2.当country为静态变量时,静态变量放在方法区当中
        • 3. 关于空指针异常
        • 4. 静态方法的使用
        • 5. 类中的东西
        • 6. 方法什么时候定义为静态的
        • 7. 不可以在main方法中定义static变量的原因
      • static静态块
        • 总结:栈、堆、方法区
        • 到目前为止,有顺序要求的执行代码有哪些?
        • 实例语句块
        • 所学的各个代码块的执行顺序
      • this关键字
        • 总结
    • java三大变量
    • 总结:
    • 继承
      • 继承的作用:
      • 继承的相关特性:
      • 测试extends
        • 1. 子类继承父类后,可以使用子类对象调用父类方法吗?
        • 2. 在实际开发中,满足什么条件是可以使用继承?
        • 3. 任何一个类,没有显示继承任何类,默认继承Object,那么Object中都有什么?
    • 方法的覆盖和多态机制
      • 方法覆盖
        • 什么时候使用方法覆盖?
        • 方法覆盖的条件
        • 注意事项
        • 经典的案例
        • 方法重载和方法覆盖有什么区别?
      • 多态
        • 向上转型和向下转型的概念
        • 什么是多态?
        • 向下转型的风险
          • 怎么避免:ClassCastException的产生
            • 新的内容,运算符:instanceof
        • 多态在实际应用中的作用
      • 解释之前遗留的问题
        • 私有方法无法覆盖。
        • 静态方法存在方法覆盖吗?
        • 在方法覆盖中,关于方法的返回值类型。
    • super关键字
      • super和this对比学
        • this:
        • super:
        • super()
        • 重要的结论
        • super和this的执行顺序
      • super(实例参数)的使用时间
      • super执行的内存图
      • “super(实参)”到底是干嘛的?
      • super关键字代表什么?
      • 例子
        • 子类型和父类型无同名属性
        • 子类型和父类型有同名属性
        • java如何区分子类属性和父类型属性
      • super不能单独使用
      • super执行的内存图
      • “super(实参)”到底是干嘛的?
      • super关键字代表什么?
      • 例子
        • 子类型和父类型无同名属性
        • 子类型和父类型有同名属性
        • java如何区分子类属性和父类型属性
      • super不能单独使用

方法

Java的主要内存空间

代码放在方法区侯先去执行main文件时,main方法在执行的时候 ,方法需要的内存空间在栈中被分配,栈是一种数据结构

栈数据结构

栈数据结构:stack

什么是数据结构?

​ 数据结构通常是:存储数据的容器,而该容器可能存在不同的结构。数据结构和java语言实际上没有任何关系,数据结构是一门独立的学科

常见的数据结构是哪些?

​ 数组、链表、图二叉、队列…java语言已经把数据结构写好了,程序员直接来用就可以。

和数据结构通常在一起的是算法:排序、查找等…

精通数据结构和算法,会提升程序的效率

方法区执行时内存的变换

入栈

弹栈

3个ix都是局部变量,方法结束后,内存空间都进行释放

package Method;
//局部变量只在方法体中有效,方法结束后,局部变量内存就失效了
//方法区中最先有数据,方法区中放代码片段,存放class字节码
//栈内存:方法调用的时候,该方法需要的内存空间在栈中分配
//方法不调用是不会在栈中分配空间的,方法只有调用的时候才会在栈中分配空间,并且调用时就是压栈
//方法执行结束后,该方法所需要的空间就会被释放,进行弹栈。/*方法调用叫做:压栈,分配空间方法结束:弹栈,释放空间栈中存储:方法执行中需要的内存,以及该方法的局部变量*/
public class test01 {//主方法入口public static void main(String[] args){System.out.println("main begin");/*int a = 100;int b = a;这里的原理是:将a变量中保存的100这个数字复制一份传给b,所以a和b是两个不同的内存空间,是两个局部变量*/int x = 100;m1(x);System.out.println("main begin");}public static void m1(int i){ //i是局部变量System.out.println("m1 begin");m2(i);System.out.println("m1 over");}public static void m2(int i){System.out.println("m2 begin");m3(i);System.out.println("m2 over");}public static void m3(int i){System.out.println("m3 begin");System.out.println(i);System.out.println("m3 over");}
}
main begin
m1 begin
m2 begin
m3 begin
100
m3 over
m2 over
m1 over
main begin

方法总结

方法的重载

package Method;
//程序先不使用方法重载,分析程序的缺点?
//程序员需要记忆过多的方法名字
//代码不够美观
public class OverloadTest01 {//主方法public static void main(String[] args){int x = sumInt(10,20);System.out.println(x);long y = sumLong(20L,10L);System.out.println(y);;double z = sumDouble(10.00,21.00);System.out.println(z);}public static int sumInt(int a, int b){return a+b;}public  static long sumLong(long a, long b){return a+b;}public static double sumDouble(double a, double b){return a+b;}
}
package Method;
/*
使用方法重载机制
优点1:代码整齐美观
优点2:可以让功能相似的方法名重合在java语言中如何进行语言区分?
首先Java编译器首先通过方法名进行区分,但是java语言中允许方法名相同的情况出现
如果方法名相同的情况下,编译器会通过方法的参数类型进行方法的区分*/
public class overloadTest02 {public static void main(String[] args){System.out.println(sum(10, 20));System.out.println(sum(10l, 20l));System.out.println(sum(20.0, 10.0));}public static int sum(int a,int b){System.out.println("int求和");return a+b;}public static long sum(long a,long b){System.out.println("long求和");return a+b;}public static double sum(double a,double b){System.out.println("double求和");return a+b;}
}

什么时候会发生方法重载?

在一个类当中功能一和功能二它们的功能是相似的;可以考虑他们的方法名是一致的,这样代码既美观,又便于后期编写

什么时候代码会发生方法重载?

  • 条件一:在同一个类当中
  • 条件二:方法名相同
  • 条件三:参数列表不同
    • 参数的类型不同;参数的个数不同;参数的顺序不同

注意:

  • 方法重载和方法的返回值类型无关
  • 方法重载和方法的修饰符列表无关
package Method;
/*
什么时候会发生方法重载?
在一个类当中功能一和功能二它们的功能是相似的
可以考虑他们的方法名是一致的,这样代码既美观,又便于后期编写
什么时候代码会发生方法重载?
条件一:在同一个类当中
条件二:方法名相同
条件三:参数列表不同参数的类型不同;参数的个数不同;参数的顺序不同*/
/*
大家是否承认println()是一个方法名字*/
public class overloadTest03 {public static void main(String[] args){//println是方法名字,是由sun公司写的,可以直接使用//println()方法肯定是重载了//对于println只需要记住一个方法名就可以了//参数类型可以随便传,这说明println()重载了System.out.println(10);System.out.println("12");System.out.println(true);}
}

方法递归

package Method;
/*1.什么是方法递归?方法自己调用自己,就是方法的递归2.当递归时,程序没有结束条件,一定会发生,栈溢出错误所以递归一定要结束条件3.*/
public class RecursionTest01 {public static void main(String[] args){doSome();}public static void doSome(){System.out.println("doSome begin");//调用方法:doSome()既是一个帆帆发,那么doSome方法可以调用吗?当然可以//目前这个方法是没有停止条件的,电脑会出现什么问题?doSome();//这行永远执行不到System.out.println("doSome over");}}代码会出现栈的内存溢出错误

1.什么是方法递归?

​ 方法自己调用自己,就是方法的递归

2.当递归时,程序没有结束条件,一定会发生,栈溢出错误所以递归一定要结束条件

3.递归假设有结束条件,就不会发生栈溢出错误么?

​ 假设结束条件是对的,是合法的,递归有时候也会出现栈内存错误,因为有可能递归太深,占内存不够了,因为一直在压栈。

4.在实际的开发中不建议轻易的使用递归,能使用for循环while循环代替的,尽量使用循环来做,因为循环的效率高,耗费的内存少递归耗费的内存比较大,另外递归地使用不当可能会导致JWM死掉(但在极少数的情况下,不用递归程序没有办法实现)

5.在实际的开发中,如果遇到这个栈溢出的错误,如何解决这个问题?

  • 第一步:先检查递归的结束条件是否正确
  • 第二步:递归条件正确,这个时候需要手动调整JVM的栈内存初始化大小可以将栈内存的空间大一些。
  • 第三步:调整了大小,如果运行时还是出现了错误,只能继续扩大栈内存的大小。
  • java-x参数可以查看调整堆栈大小的参数
package Method;
/*
不用递归 计算1-n的和*/
public class RecursionTest02 {public static void main(String[] args){int N = 100;int res = sum(N);System.out.println(res);}public static int sum(int n){int result = 0;for(int i = 1; i<= n ; i++){result += i;}return result;}
}
package Method;/*
使用递归 求1-n的和*/
public class RecursionTest03 {public static void main(String[] args){System.out.println(sum(100));}public static int sum(int n) {if (n == 1) {return 1;}return n + sum(n - 1);}
}

递归内存图

递归求阶乘
package Method;/*
使用递归 求阶乘*/
public class RecursionTest03 {public static void main(String[] args){System.out.println(jicheng(5));}public static int jicheng(int n){if(n ==1 ){return 1;}return n * jicheng(n-1);}
}

认识面向对象

1. 面向过程和面向对象有什么区别?

2. 当我们采用面向对象的方式贯穿整个系统的时候,涉及到三个术语:

OOA:面向对象的分析

OOD:面向对象的设计

OOP:面向对象的编程

整个软件开发的过程,都是采用OO进行贯穿的

实现一个软件的过程:

​ 分析A ➡ 设计D ➡ 编程P

3. 面向对象的三大特征

封装、继承、多态

任何一个面向对象的编程语言都包括这三个特征:比如python

注意:java只是面向对象语言中的一种。

4. 类和对象的概念

什么是类?

类实际上在现实世界当中是不存在,是一个抽象的概念,是一个模板,是我们人类大脑进行思考的结果、总结、抽象的一个结果

​ 明星是一个类

什么是对象?(真实存在个体)

对象是实际存在个体,对象还有另外一个名称叫做实例

通过类创建对象的过程,叫做实例化

​ 姚明是一个对象

​ 刘德华是一个对象

​ 这两个对象都是明星这个类

在java语言中,要想得到“对象”,必须先定义“类”,“对象”就是通过“类”,这个模板创造出来的

​ 类就是一个模板:类中描述的是所有对象的“共同特征信息”

​ 对象就是通过类创建出来的个体

类 ——[实例化] ——> 对象(实例)
对象 ——[抽象] ——> 类

类的共同特征

类是一个模板,是描述一个共同特征的模板,那么共同特征是什么?

​ 状态特征、动作特征

​ 类= 属性+ 方法

  • 属性来源于:状态
  • 方法来源于:动作

5. java软件工程师在开发中起到的作用是什么?

​ java是转换虚拟世界和现实世界的桥梁

6. 类的定义

怎么定义一个类,语法格式是什么?

[修饰符列表] class 类名{//类= 属性 + 方法//属性在代码上以“变量”的形式存在//方法描述动作;属性描述状态}

为什么属性以“变量”的形式存在?

属性对应的是数据,数据只能放到变量中

结论:属性就是变量

变量:根据出现的位置进行划分:

  • 方法体中声明的变量:局部变量
  • 方法体外声明的变量:成员变量
package lei;
/*
1.学生的共同特征:学号int、姓名String、性别char、住址String注意:属性是成员变量*///Students既是一个类名又是一个类型名,属于引用数据类型
public class Students {//属性//成员变量int xuehao;String name;int age;boolean gender;String adress;}
package lei;
/*
对象的创建和使用
创建对象的语法是什么?*/
public class StudentTest {public static void main(String[] args){//可以可以使用Student类的/*创建对象的语法;newnew 类名();new是一个运算符,专门负责对象的创建数据类型 变量名 = new 类名();数据类型包括两种:基本数据类型和引用数据类型java中所有的”类“都是引用数据类型*/Students s = new Students();//Students是一个引用数据类型//new Students() 是一个对象}
}

7. 编译的过程

对象的创建与使用

对象的创建

类名 变量名 = new 类名();

这样就完成了对象的创建

变量必须先声明,在赋值才能访问
注意:对于成员变量来说,没有手动赋值 ,系统自动赋值,为默认值

​ 类型 默认值
​ byte 0
​ short 0
​ long 0L
​ int 0
​ float 0.0F
​ double 0.0
​ boolean flase
​ char \u000
​ 引用数据类 null

什么是实例变量

实例是对象,对象又被称为实例;

实例变量实际上就是:对象级别的变量

堆内存中存储对象,以及对象的实例变量

实例变量在访问的时候,是不是必须先创建对象?

//访问学生姓名可以直接通过类名嘛?
//学生姓名是一个实例变量,实例变量是对象级别的变量
//是不是先有对象才可以有姓名
//不能通过类名直接访问实例变量
//System.out.println(Students.name);

对象和引用的区别?

对象是通过new出来,在堆内存中存储

引用是:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的叫做引用

引用是:存储对象内存地址的一个变量

通俗一点说:只要这个变量中保存的是一个对象的内存地址,这个变量就叫做引用

对象是:堆里new出来的

访问id不能使用User.id,这是错误的,实例变量不能用类名访问。id的访问必须是先造对象,然后有了对象,才能访问对象的id

思考:引用一定是局部变量吗? 不一定是。

JVM中的三个主要内存

栈:主要存储局部变量以及类对象的地址,方法执行时所需要的空间局部变量;只要是方法体中的局部变量,都在栈中进行分配

堆内存:主要存储对象以及对象的实例变量实例变量

方法区:主要存储代码片段

内存图例子:

例子2:

package lei;
/*
记住:里面有什么就能点.什么
所有实例变量都是通过”引用.“来访问的*/
public class Test01 {public static void main(String[] args){Address a = new Address();a.city = "北京";a.street = "大兴区";a.zipcode = "10010";System.out.println(a.city);System.out.println(a.street);System.out.println(a.zipcode);Users user1 = new Users();user1.add = a;user1.id = 123;user1.name = "yxy";/*System.out.println("============”=“代表赋值运算===============");int x = 100;int y = x;表示把x变量中保存的值100复制一份给y*//*Add K = new Add();Add m = k;Add k = 0x1111;那么 m = 0x1111;*///在java中只有值进行传递,值可能是变量、地址等等System.out.println(user1.id);System.out.println(user1.name);System.out.println(user1.add.city);System.out.println(user1.add.zipcode);System.out.println(user1.add.street);}
}
/*
*引用是:存储对象内存地址的一个变量**
通俗一点说:只要这个变量中保存的是一个对象的内存地址,这个变量就叫做引用
*对象是:堆里new出来的**
*
* 思考:引用一定是局部变量吗?
*  不一定是*/
package lei;public class Address {String city;String street;String zipcode;
}
package lei;public class Users {int id;String name;Address add;}

属性的引用

package lei;public class T {A a;public static void main(String[] args){A a = new A();B b = new B();C c = new C();D d = new D();T t = new T();c.d = d;b.c = c;a.b = b;t.a = a;System.out.println(t.a.b.c.d.i);}}
class A{B b;
}
class B{C c;
}
class C{D d;
}
class D{int i = 100;
}

空指针

package lei;
/*
空指针异常*/
public class NullPointerTest {public static void main(String[] args){//创建客户对象Customer c = new Customer();//访问这个对象的idSystem.out.println(c.id);//重新给id赋值c.id = 45;System.out.println(c.id);c =null;/*编译器没问题,因为编译器只检查语法,编译器发现c是Customer类型,Customer类型中有id属性,所以可以但是运行的时候需要对象的存在,但是对象没了,只能抛出一个异常*/System.out.println(c.id);/*空指针错误Exception in thread "main" java.lang.NullPointerExceptionat lei.NullPointerTest.main(NullPointerTest.java:16)*/}
}
class Customer{int id; //成员变量中的实例变量,应该先创建对象,然后通过”引用.“的方式访问
}

关于垃圾回收器GC,在java语言中,java回收器主要针对的是堆内存,当一个java对象没有任何引用指向该对象的时候,GC会考虑将垃圾数据释放被回收。

出现空指针异常的条件是:”空引用“访问实例相关数据时,都会出现空指针异常

方法调用时的参数传递

java中规定:参数传递的时候,和类型无关,无论是基本类型还是引用数据类型,同意都是盒子中保存的值,复制一份传递下去

package canshuchuandi;
//分析程序的参数传递
//java中规定:参数传递的时候,和类型无关,无论是基本类型还是引用数据类型,同意都是盒子中保存的值,复制一份传递下去public class Test01 {public static void main(String[] args){int i = 10;add(i);System.out.println("main-->" + i); //10}public static void add(int i){ // i在add域中//把main中i变量盒子中保存的10这个数复制了一份,传给了add方法i++;System.out.println("add-->" + i); //11}
}

package canshuchuandi;public class Test02 {public static void main(String[] args) {Person p = new Person();p.age = 10;add(p);System.out.println("main -->" + p.age); //11}//方法可以是基本数据类型,也可以是引用数据类型,只要是合法的数据类型就可public static void add(Person p){p.age++;System.out.println("add -->" + p.age); //11}
}class Person{int age;
}

这两个p是不同的局部变量

构造方法Constructor

1.什么是构造方法?有什么用?

构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建以及实例变量的初始化,

换句话说构造方法是用来创建对象并且给对象的属性赋值的(注意:实例变量没有手动赋值的时候,系统会赋默认值)

2.当一个类没有提供任何构造方法,但是系统实际上会默认提供一个无参数的构造方法,(这个方法会被称为缺省构造器)

3.调用构造方法如何使用呢?

使用new运算符来构造方法;语法格式:new 构造方法名(实际参数列表)

4.构造方法的语法结构是什么?

[修饰符列表] 构造方法名(形式参数列表){构造方法体;}

注意:1.修饰符列表目前统一写public 千万不要写 public static

2.构造方法名和类名必须一致

3.构造方法名不需要指定任何返回值类型,不需要写void

普通方法的语法结构

 [修饰符列表] 返回值类型 方法名(形式参数列表){方法体;
}

5.无参数的构造方法和有参数的构造方法

  1. 当一个类中没有提供任何构造方法,系统默认提供一个无参数的构造方法,这个无参数的构造方法叫做缺省构造器。

  2. 如果一个类中手动的提供了构造方法,那么系统将不会提供无参构造方法了,建议手动将无参构造方法写出来,这样一定不会出问题

  3. 无参数的构造方法和有参数的构造方法都可以调用

  4. 构造方法支持方法重载么?

    可以支持方法重载,在一个类中构造方法可以有多个,并且所有的构造方法的名字都是一样的

    方法重载有一个特点:

    ​ 在同一个类中,方法名字相同,参数列表不同

  5. 对于实例变量来说,只要你在构造方法中没有手动赋值,那么系统就会默认赋值

  6. 构造方法的作用:创建对象,并给属性赋值

package Constructor;
/*
构造方法:1.什么是构造方法?有什么用?构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建以及实例变量的初始化,换句话说构造方法是用来创建对象并且给对象的属性赋值的(注意:实例变量没有手动赋值的时候,系统会赋默认值)2.当一个类没有提供任何构造方法,但是系统实际上会默认提供一个无参数的构造方法,(这个方法会被称为缺省构造器)3.调用构造方法如何使用呢?使用new运算符来构造方法语法格式:new 构造方法名(实际参数列表)4.构造方法的语法结构是什么? 没有返回值类型 不能写void[修饰符列表] 构造方法名(形式参数列表){构造方法体;}注意:1.修饰符列表目前统一写public 千万不要写 public static2.构造方法名和类名必须一致3.构造方法名不需要指定任何返回值类型,不需要写void普通方法的语法结构[修饰符列表] 返回值类型 方法名(形式参数列表){方法体;}*/
public class Test01 {public static void main(String[] args){//调用无参数构造方法new Students();//调用普通方法Test01.doSome();doSome();//调用Students类的无参数构造方法//创建students类型的对象Students s1 = new Students();System.out.println(s1); //输出哈希值//调用有参数的构造方法Students s2 = new Students(100);System.out.println(s2);}//普通构造方法public static void doSome(){System.out.println("ds");}
}
class Students{int no;int age;String name;//当Students没有构造方法时,系统实际上会默认提供一个无参数的构造方法//构造方法public Students(){System.out.println("无参数执行");}public Students(int no) {this.no = no;}//重载//public void Students(String name){}public Students(String name){this.name = name;}
}

调用不同构造方法创造对象

package Constructor;public class Test03 {public static void main(String[] agrs){//调用不同的构造方法创建对象Vip v1 = new Vip();Vip v2 = new Vip(111,"y");Vip v3 = new Vip(222,"x","123");Vip v4 = new Vip(333,"y","123",true);System.out.println(v1.no);System.out.println(v1.name);System.out.println(v1.birth);System.out.println(v1.sex);System.out.println("----------------------");System.out.println(v2.no);System.out.println(v2.name);System.out.println(v2.birth);System.out.println(v2.sex);System.out.println("----------------------");System.out.println(v3.no);System.out.println(v3.name);System.out.println(v3.birth);System.out.println(v3.sex);System.out.println("----------------------");System.out.println(v4.no);System.out.println(v4.name);System.out.println(v4.birth);System.out.println(v4.sex);}
}
0
null
null
false
----------------------
111
y
null
false
----------------------
222
x
123
false
----------------------
333
y
123
trueProcess finished with exit code 0

面向对象的三大特征-封装、继承、多态

有了封装才有继承,有了继承,才有多态

封装

什么是封装?有什么用?

​ 现实生活中有很多现实的例子都是封装的,例如:手机、电视机等

​ 封装起来,保护内部的部件,另外封装之后, 对于我们使用者来说,我们是看不见内部的复杂结构的。

封装的作用

一个类体当中的数据,假设封装之后,对于代码的调用人员来说,不需要关心代码的复杂实现,是需要通过一个简单的入口就可以访问了,另外,类体中安全级别较高的数据封装起来 ,外部人员不能随意访问,来保证数据的安全性。

怎么进行封装

第一步:属性私有化,private、

第二步:对外提供简单的操作入口,对外提供公开的set方法和get方法,并且这两个方法都不带有static,为对象级别的方法

​ 可以在set方法中设立关卡,来保护数据的安全性

注意:java开发规范中,set方法和get方法要满足以下格式 不可以带static

get方法的要求:public 返回值类型 get+属性名首字母大写(无参){return xxx;}
set方法的要求:public void+属性名首字母大写(有一个参数){xxx = 参数;}

无封装的情况:

package fengzhuang;
//在外部程序中访问Person
public class PersonTest {public static void main(String[] args){//创建Person对象Person p1 = new Person();//访问对象的属性,一般分为两种操作,一种是读数据,一种是改数据p1.age = 50;System.out.println(p1.age);//在Person这个外部程序中,目前可以随意对age进行操作}
}
class Person {//实例变量、属性int age;}

有封装的情况:

package fengzhuang;
//在外部程序中访问Person
public class PersonTest {public static void main(String[] args) {//private 表示私有的,被这个关键字修饰之后,该数据只能在本类中访问,除了这个类,这个属性将不能被访问/*Person age,彻底在外部不能进行访问p1.age = 20;//读取System.out.println(p1.age);*/Person p1 = new Person();//通过类名.不可以调用get和set方法。p1.setAge(-1);int age = p1.getAge();System.out.println(age);}
}
package fengzhuang;//这是没有封装的Person
/*public class Person {//实例变量、属性int age;}
*/
//开始封装代码,不在对外暴露复杂的数据
//封装起来,保护内部的数据,保证其安全性
public class Person{//属性私有化private int age;//对外提供简单的操作入口/*写专门的方法来完成读写(get、set)对外提供公开的set方法和get方法,并且这两个方法都不带有static,为对象级别的方法*///注意:java开发规范中,set方法和get方法要满足以下格式/*get方法的要求:public 返回值类型 get+属性名首字母大写(无参){return xxx;}set方法的要求:public void+属性名首字母大写(有一个参数){xxx = 参数;}*/public int getAge(){return age;}public void setAge(int age) {if(age <0 || age >150){System.out.println("年龄不合法");return; //程序终止}this.age = age;}
}

static关键字

静态变量在类加载时进行初始化

  1. 所有static关键字修饰的都是类相关的,类级别的
  2. 所有static修饰的,都是采用“类名."的方式访问的
  3. static修饰的变量:静态变量
  4. static修饰的方法:静态方法

变量的分类:

​ 变量根据声明的位置进行划分:在方法体内的变量叫做:局部变量;

​ 在方法体外的变量叫做:成员变量。

​ 成员变量又可以分为:

​ 实例变量

​ 静态变量

1.当county不是静态变量的时候:会导致内存的浪费,country放在堆中

package Staticpackage;
/*
什么时候声明为静态的,什么时候声明为实例的*/
public class Test02 {public static void main(String[] args){Chinese c1 = new Chinese("123456","yxy");Chinese c2 = new Chinese("123456789","yxa");}
}
class Chinese{//身份证号应该为实例变量,一个人一份//姓名也应该是实例变量String idCard;String name;//国籍是一个固定值,所以是静态变量String country;public Chinese() {}public Chinese(String idCard, String name) {this.idCard = idCard;this.name = name;}
}

2.当country为静态变量时,静态变量放在方法区当中

package Staticpackage;
/*
什么时候声明为静态的,什么时候声明为实例的
如果这个对象的某个属性值都是一样的,不建议定义为实例变量,建议定义为类级别特征,定义为静态变量,在方法区中保留,节省开销*/
public class Test02 {public static void main(String[] args){//静态变量的输出System.out.println(Chinese.country);Chinese c1 = new Chinese("123456","yxy");Chinese c2 = new Chinese("123456789","yxa");System.out.println(c1.idCard);System.out.println(c1.name);System.out.println(c2.idCard);System.out.println(c2.name);//System.out.println(Chinese.idCard);//程序报错,因为idCard时实例变量,必须通过引用.访问}
}
class Chinese{//身份证号应该为实例变量,一个人一份//姓名也应该是实例变量String idCard;String name;//声明为静态变量也具有初始值,为null,这个初始值在类加载时进行初始化//并且静态变量存在方法区//国籍是一个固定值,所以是静态变量static String country = "中国";public Chinese() {}public Chinese(String idCard, String name) {this.idCard = idCard;this.name = name;}
}

3. 关于空指针异常

package Staticpackage;
/*实例的:应引用.来访问静态的:建议使用”类名.“来访问结论:空指针异常只有在”空引用“访问”实例“相关的,都会出现空指针异常*/
public class Test03 {public static void main(String[] args){System.out.println(Chinese.country);//创建对象Chinese c1 = new Chinese("11", "yxy");System.out.println(c1.country);System.out.println(c1.name);System.out.println(c1.idCard);//空引用c1 = null;//不会出现空指针异常,因为静态变量不需要对象的存在,这个代码实际上还是System.out.println(Chinese.country);System.out.println(c1.country);}}
class Chinese{String idCard;String name;public Chinese() {}static String country = "中国";public Chinese(String x, String y){idCard = x;name = y;}
}

4. 静态方法的使用

package Staticpackage;public class Test04 {public static void main(String[] args){Test04.dosome();Test04 st = new Test04();st.doOther();}//静态方法不需要new对象,采用类名.public static void dosome(){System.out.println("静态方法do some");}//实例方法都需要new对象,使用”引用.“来访问public void doOther(){System.out.println("实例方法");}
}

5. 类中的东西

6. 方法什么时候定义为静态的

参考标准:当这个方法体当中,访问了实例变量,那么一定是实例方法。大部分情况下,如果是工具类的方法一般都是静态的(静态方法不需要new对象,直接采用类型调用,极其的方便,工具类就是为了方便,所以工具类中的方法一般为static)实例方法的定义:不同对象参加考试的结果不同,我们可以认为考试是与对象相关的东西,那么我们把考试定义为实例方法

package Staticpackage;
/*
什么时候定义为实例方法,什么时候定义为静态方法参考标准:当这个方法体当中,访问了实例变量,那么一定是实例方法大部分情况下,如果是工具类的方法一般都是静态的(静态方法不需要new对象,直接采用类型调用极其的方便,工具类就是为了方便,所以工具类中的方法一般为static)实例方法的定义:不同对象参加考试的结果不同,我们可以认为考试是与对象相关的东西,那么我们把考试定义为实例方法*/
//类 = 属性 + 方法
public class Test05 {public static void main(String[] args){}
}
class User{//实例变量,需要对象rprivate int id;private String name; //首先name是对象级别的。//打印用户的名字,是实例方法public void printName(){}// 先new一个对象才可以get和set方法public void setId(int i){id = i;}public int getId(){return id;}
}

7. 不可以在main方法中定义static变量的原因

只有类才存在静态的变量,方法只能对静态变量的操作,不能在方法内试图定义静态变量

static静态块

  1. static可以定义静态代码块
语法结构:static{java语句;java语句;}
  1. 执行时间:类加载时执行,并且只执行一次

  2. 注意:一个类当中可以写多个静态代码块,静态代码块在类加载时执行,并且在main方法执行前执行,静态代码块一般按照自上而下的顺序执行

  3. 静态代码块的作用:记录项目日志

    特殊的时机:类加载的时机,放代码

package Staticpackage;
/*
static可以定义静态代码块
语法结构:static{java语句;java语句;}
执行时间:类加载时执行,并且只执行一次
特点:一个类当中可以写多个静态代码块,静态代码块在类加载时执行,并且在main方法执行前执行,静态代码块一般按照自上而下的顺序执行***/
public class Test06 {//静态代码块static{System.out.println("A");}//一个类中可以定义多个静态代码块static{System.out.println("B");}public static void main(String[] agrs){System.out.println("hello word");}static{System.out.println("C");}}

静态变量在类加载时初始化,静态代码块在类加载时执行,所以静态代码块可以访问静态变量,

实例变量的初始化是在new对象的时候开始,在构造方法执行时内存空开才会开辟

总结:栈、堆、方法区

栈:只要方法执行,就会进行压栈操作,栈会提供方法所需要的空间,栈内存放局部变量

堆:堆内存放实例变量,new出来的对象

方法区:类的信息、存放代码片段和静态变量

到目前为止,有顺序要求的执行代码有哪些?

实例语句块

package Staticpackage;public class InstanceCode {//入口public static void main(String[] args){new InstanceCode();new InstanceCode();new InstanceCode("abc");}//实例语句块 不在类加载时执行{System.out.println("实例语句执行");}public InstanceCode() {System.out.println("无参数构造");}public InstanceCode(String name) {System.out.println("有参数构造");}}

实例语句块,不在类加载时执行,在构造器执行之前执行,并且在每一次new对象时,都执行一次

所学的各个代码块的执行顺序

package Staticpackage;
//判断执行顺序
public class CodeOrder {static{System.out.println("A");}public static void main(String[] args){System.out.println("main begin");new CodeOrder();System.out.println("main over");}public CodeOrder() {System.out.println("B");}{System.out.println("C");}static{System.out.println("X");}
}
A
X
main begin
C
B
main over

this关键字

  1. this 是一个关键字,全部小写

  2. 一个对象一个this,this是一个变量,是一个引用。this保存当前对象的内存地址,指向自身,所以,严格意义上来说,this代表的是“当前对象”,this存储在堆内存当中对象的内部。

  3. this只能使用在实例方法中。谁调用这个实例方法,this就是谁,所以this代表的是当前对象。

  4. this.大部分情况下是可以省略的

  5. 为什么this不可以使用在静态方法中?

    this代表的是当前对象,而静态方法的调用不需要对象

  6. 在实例方法中,或者构造方法中,为区分局部变量和实例变量,这种情况下this是不可以省略的

    //this不可以省略的情况package Staticandthis;
    /*
    this 可以使用在实例方法中,不能使用在静态方法中,this关键字大部分情况下可以省略在实例方法中,或者构造方法中,为区分局部变量和实例变量,这种情况下this是不可以省略的*/
    public class Test09 {public static void main(String[] args){System.out.println("——————无参数构造——————");Students s = new Students();s.setName("yxy");s.setNo(1);System.out.println(s.getName());System.out.println(s.getNo());System.out.println("——————有参数构造——————");Students s2 = new Students(2,"yx");System.out.println(s2.getName());System.out.println(s2.getNo());}
    }
    class Students{private int no;private String name;public Students() {}//this.no是一个实例变量// no是一个局部变量public Students(int no, String name) {this.no = no;this.name = name;}public void setNo(int no) {this.no = no;}public void setName(String name) {this.name = name;}//getName实际上获取的是当前名字的public int getNo() {return no;//return this.name}public String getName() {return name;}
    }
    

package Staticandthis;
/*1.this是一个关键字,全部小写2.this是什么,在内存方面是怎么样的?this是一个变量,是一个引用,this保存当前对象的内存地址,指向自身一个对象一个this所以严格意义上来说,this代表的就是“当前对象”,this存储在堆内存当中*/
public class Test08 {public static void main(String[] args){Customer c1 = new Customer("yxy");c1.shopping(); //this 代表c1,c1调用shopping,this就是c1Customer c2 = new Customer("x");Student.m();}}
class Customer {String name;public Customer() {}public Customer(String s) {name = s;}//顾客购物方法 实例方法public void shopping() {//c1调用shopping,this就是c1//c2调用shopping,this就是c2System.out.println(this.name + "正在购物");//引用.就是this. this.是可以省略的}public static void doSome() {//this代表的是当前对象,而静态方法的调用不需要对象// System.out.println(this);}
}
class Student{//实例变量,必须new对象,通过引用.来访问String name = "z";//所以name不能访问public static void m(){// System.out.println(name);//可以这样Student s = new Student();System.out.println(s.name);//方法中直接访问了实例变量,那么必须是实例方法}
}
yxy正在购物
z
  1. 新语法:通过当前的构造方法去调用另一个本类的构造方法,可以使用以下语法格式:

    this(实际参数列表);

    通过一个构造方法1去调用构造方法2,可以做到代码复用,但是需要注意的是:构造方法1和构造方法2都是在同一个类当中

    新语法的作用是:代码复用

    在构造方法中:this()前面不可以有其他的语句,并且只可以出现一次。

    package Staticandthis;
    /*
    this` 可以用在实例方法以外,还可以用在构造方法中
    新语法:通过当前的构造方法去调用另一个本类的构造方法,可以使用以下语法格式:this(实际参数列表);*/
    public class Test10 {public static void main(String[] args) {Date d1 = new Date();d1.setDay(10);Date d2 = new Date(2000, 01, 01);d1.detail();d2.detail();}
    }
    class Date{private int year;private int month;private int day;public Date(){//错误:对this 的调用必须是构造器中的第一个语句// System.out.println(11);/* this.year = 1970;this.month = 1;this.day = 1;*/this(1970,1,1);}public Date(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}//提供一个打印方法public void detail(){System.out.println(year + "," + month + "," + day);}public void setYear(int year) {this.year = year;}public void setMonth(int month) {this.month = month;}public void setDay(int day) {this.day = day;}public int getYear() {return year;}public int getMonth() {return month;}public int getDay() {return day;}}
    

总结

package Staticandthis;public class Test11 {public static void main(String[] args){//创建账户Account a = new Account("1000",2000,1.23);//创建客户对象//传a是想让Customer和Account对象产生关系//把a的内存地址直接赋值给变量actCustomers c = new Customers("yx",a);c.getAct().deposit(100);c.getAct().withdraw(960);c.getAct().withdraw(2000);}
}
//账户类
class Account{private String id;private double balacen;private double annualInterestRate;public Account() {}public Account(String id, double balacen, double annualInterestRate) {this.id = id;this.balacen = balacen;this.annualInterestRate = annualInterestRate;}public void setId(String id) {this.id = id;}public void setBalacen(double balacen) {this.balacen = balacen;}public void setAnnualInterestRate(double annualInterestRate) {this.annualInterestRate = annualInterestRate;}public String getId() {return id;}public double getBalacen() {return balacen;}public double getAnnualInterestRate() {return annualInterestRate;}//存款方法public void deposit(double money){if(money > 0){// balacen = money + balacen;// return balacen;// 调用方法来修余额setBalacen(getBalacen() + money);System.out.println("成功存入" + money);}else {System.out.println("请输入正确金额");return;}}//取款方法public void withdraw(double money){if(money < getBalacen()){//balacen = balacen -money;//return balacen;setBalacen(getBalacen() - money);System.out.println("成功取出" + money);}else {System.out.println("余额不足");return;}}
}class Customers{private String name;private Account act;public Customers() {}public Customers(String name, Account act) {this.name = name;this.act = act;}public String getName() {return name;}public Account getAct() {return act;}public void setName(String name) {this.name = name;}public void setAct(Account act) {this.act = act;}
}

java三大变量

总结:

所有的变量如何访问

所有的方法如何访问

一个类中都有什么

程序无论怎么变化,有一个固定的规律
所有的实例相关的都是先创建对象,通过”引用.“来访问
所有的静态相关的都是直接采用”类名.“来访问

结论:
只要是负责调用的方法a和被调用的方法b在同一个类当中:
this.
类名. 可以省略

package Staticandthis;
/*
类体{实例变量;实例方法;静态变量;静态方法;构造方法;静态代码块;实例语句块;方法(){局部变量;}
}*/
public class Review {//在程序执行之前,将所有的类全部加载到JVM中//先完成加载才会执行main方法static{System.out.println("Review类加载");}//静态方法public static void main(String[] args){//局部变量int i = 100;//完成全部的动作stu s1 = new stu();s1.study();}
}
//学生类
class stu{private int no;private String name;static String job = "学习";{System.out.println("实例语句块,这个构造方法执行一次,这里就执行一次");}public stu(int no, String name) {this.no = no;this.name = name;}public stu() {//默认学生的学号和姓名this(100,"yxy");}//提供两个实例方法//在实例方法中调用本类其他的实例方法public void study(){//System.out.println(this.getName() + "在努力学习");System.out.println(name + "在努力学习");//this.可以省略//eat();this.eat();}public void eat(){System.out.println(name + "在餐厅吃饭");//静态方法使用类名.的方式//在同一个类当中,类名.可以省略stu.m1();}//提供两个静态方法public static void m1(){System.out.println("M1 method");m2();}public static void m2(){System.out.println("M2 method");System.out.println("状态" + job);//stu.job}public int getNo() {return no;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
package Staticandthis;
/*
程序无论怎么变化,有一个固定的规律所有的实例相关的都是先创建对象,通过”引用.“来访问所有的静态相关的都是直接采用”类名.“来访问结论:只要是负责调用的方法a和被调用的方法b在同一个类当中:this.类名. 可以省略*/
public class Review02 {int i = 100;static int j = 1000;public void m1(){}public void m2(){}public void x(){ // 这个方法是实例方法,执行这个方法的过程中,当前对象是存在的m1(); //this.m1();m2();m3();m4();System.out.println(i);System.out.println(j);//访问其他类的静态方法T.t2();//访问其他类的实例方法T t = new T();t.t1();}public static void m3(){}public static void m4(){}/*第一步:main 方法是静态的,JVM调用main方法的时候直接采用的是”类名.“的方式、所以main方法中没有this第二步:m1() m2()都是实例方法,按照java语法来说,应该先new对象,在用过”引用.“的方式进行访问*/public static void main(String[] args){// System.out.println(i);System.out.println(j);// m1();// m2();m3();m4();//想要访问m1 m2 先new对象Review02 r = new Review02();r.m1();r.m2();System.out.println(r.i);//局部变量 可以直接访问int k = 10;System.out.println(k);T t = new T();t.t1();T.t2();}
}class T{public void t1(){}public static void t2(){}
}

继承

继承的作用:

​ 基本作用:子类继承父类,代码可以得到复用

主要作用:因为有了继承关系,才有了后期的方法覆盖和多态

继承的相关特性:

① B类继承 A类,则称 A类为超类(superclass)、父类、基类,B类则称为子类(subclass)、 派生类、扩展类。

java 中的继承只支持单继承,不支持多继承,C++中支持多继承,这也是 java 体 现简单性的一点,换句话说,java 中不允许这样写代码:

​ class B extends A,C{ }。

③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,

​ 例如:class C extends B,class B extends A,也就是说,C 直接继承 B,其实 C 还间接继承 A。

④ java 中规定,子类继承父类,除构造方法外,剩下都可以继承。但是私有的属性无法在子类中直接访问,可以通过间接的手段

⑤ java 中的类没有显示的继承任何类,则默认继承 Object 类,Object 类是 java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有 Object 类型中所有的特征。

⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间耦合度非常高,Account 类发生改变之后会马上影响到 CreditAccount 类

对继承自Object

测试extends

1. 子类继承父类后,可以使用子类对象调用父类方法吗?

本质上,子类继承父类后,是将父类继承过来的方法归自己所有,实际上调用的也不是父类的方法,是子类自己的方法,是属于子类的方法

package Extends;
/*
测试,子类继承父类,可以使用子类对象调用父类对象吗?本质上,子类继承父类后,是将父类继承过来的方法归自己所有,实际上调用的也不是父类的方法,是子类自己的方法,是属于子类的方法*/
public class Test02 {public static void main(String[] args){Cats c = new Cats();c.move();System.out.println(c.name);}
}
class Animal{//名字不封装String name = "x";//给一个默认值public void move(){System.out.println(name + "正在移动");}
}
//Cats继承Animal会将所有的东西继承过来
class Cats extends Animal{}

2. 在实际开发中,满足什么条件是可以使用继承?

凡是采用“is a”能描述的,都可以继承

​ 例如:cat is a animal

假设以后的开发中,有一个A类和一个B类,A类和B类确实有重复的代码,那么他们两个之间就可以继承吗?不一定,还要看一看他们之间是否能够用“is a”来描述

​ class Customer{
​ String name; // 名字
​ // setter and getter
​ }

​ class Product{
​ String name; // 名字
​ // setter and getter
​ }

​ class Product extends Customer{

​ }

以上的继承就属于很失败的。因为:Product is a Customer,是有违伦理的。

3. 任何一个类,没有显示继承任何类,默认继承Object,那么Object中都有什么?

java为什么比较好学呢?
是因为Java内置了一套庞大的类库,程序员不需要从0开始写代码,程序员可以基于这套庞大的类库进行“二次”开发。(开发速度较快,因为JDK内置的这套库实现了很多基础的功能。)

​ 例如:String是SUN编写的字符串类、System是SUN编写的系统类。这些类都可以拿来直接使用。

JDK源代码在什么位置?
C:\Program Files\Java\jdk-13.0.2\lib\src.zip

你现在能看懂以下代码了吗?
System.out.println(“Hello World!”);
System.out 中,out后面没有小括号,说明out是变量名。

另外System是一个类名,直接使用类名System.out,说明out是一个静态变量。

System.out 返回一个对象,然后采用“对象.”的方式访问println()方法

package Extends;
//idea中 蓝色是关键字
//黑色的标识符
//System.out.println("Hello word");
//以上代码中System、out、println都是标识符
public class Test03 {static Student s = new Student();public static void main(String[] args){//入口Test03.s.ex();//类.静态变量.方法System.out.println("Hello word");}
}
class Student{public void ex(){System.out.println("考试。");}
}

Object其中有一个叫做toString()的,我们进行了测试,发现:
System.out.println(引用);
当直接输出一个“引用”的时候,println()方法会先自动调用“引用.toString()”,然后输出toString()方法的执行结果。

package Extends;
/*
默认继承Object,Object中有哪些方法?
package java.lang;import jdk.internal.vm.annotation.IntrinsicCandidate;public class Object {@IntrinsicCandidatepublic Object() {}@IntrinsicCandidatepublic final native Class<?> getClass();@IntrinsicCandidatepublic native int hashCode();public boolean equals(java.lang.Object obj) {return (this == obj);}@IntrinsicCandidateprotected native java.lang.Object clone() throws CloneNotSupportedException;public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}@IntrinsicCandidatepublic final native void notify();@IntrinsicCandidatepublic final native void notifyAll();public final void wait() throws InterruptedException {wait(0L);}public final native void wait(long timeoutMillis) throws InterruptedException;public final void wait(long timeoutMillis, int nanos) throws InterruptedException {if (timeoutMillis < 0) {throw new IllegalArgumentException("timeoutMillis value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {timeoutMillis++;}wait(timeoutMillis);}@Deprecated(since="9")protected void finalize() throws Throwable { }
}*/
public class Test05 {public static void main(String[] args){Test05 t = new Test05();String r = t.toString();System.out.println(r); //Extends.Test05@1b6d3586   1b6d3586 可以等同看作是对象在堆内存当中的内存地址,实际上是内存地址经过哈希算法得出的结果product p = new product();String r2 = p.toString();System.out.println(r2);System.out.println(p.toString());//如果直接输出引用呢System.out.println(p);//默认调用toString方法}
}
class product{/*public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}*/}
Extends.Test05@1b6d3586
Extends.product@4554617c
Extends.product@4554617c
Extends.product@4554617c

方法的覆盖和多态机制

方法覆盖

什么时候使用方法覆盖?

当子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,子类有权利对这个方法进行重新编写,有必要进行方法的覆盖,方法覆盖又叫做方法重写Override

方法覆盖的条件

条件一:两个类必须具有继承关系

​ 继承的两个作用:基本作用和重要作用
​ 基本作用:代码复用
​ 重要作用:方法覆盖和多态机制

条件二:重写之后的方法和继承过来的方法具有

​ 相同的返回值类型,
​ 相同的方法名,
​ 相同的形式参数列表

条件三:访问权限不能更低,可以更高

条件四:重写之后的方法不能比之前的方法抛出的更多,可以更少

package Override;
/*
什么时候会考虑使用方法覆盖:当子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,子类有权利对这个方法进行重新编写,有必要进行方法的覆盖,
方法覆盖又叫做方法重写Override重要结论:当子类对父类继承过来的方法进行方法重写之后,那么创建子类对象,对象调用的一定是覆盖后的方法
回顾以下方法重载:什么时候开率使用方法重载?overload当在一个类当中,如果功能相似的话,建议将名字定义的一样,这样代码美观,并且方便编程什么条件满足方法重载?条件一:在同一个类当中条件二:方法名相同条件三:参数列表不同(个数,顺序,类型)当我们代码怎么编写的时候,在代码级别上构成了方法覆盖呢?条件一:两个类必须具有继承关系继承的两个作用:基本作用和重要作用基本作用:代码复用重要作用:方法覆盖和多态机制条件二:重写之后的方法和继承过来的方法具有相同的返回值类型,相同的方法名,相同的形式参数列表条件三:访问权限不能更低,可以更高条件四:重写之后的方法不能比之前的方法抛出的更多,可以更少*/
public class Test02 {public static void main(String[] args){Brid b =new Brid();b.move();b.sing(1);Cat c = new Cat();c.move();}
}
class Animal{public void move(){System.out.println("动物在移动!");}//父类有抛出异常/*public void move() throws Error{System.out.println("动物在移动!");}*///更低的权限可以被public访问/*protected void move(){System.out.println("动物在移动!");}*/public void sing(int i){System.out.println("Animal singing");}
}
class Brid extends  Animal{//对move方法进行方法覆盖,方法重写,override//最好将父类中的方法原封不动的复制过来(不建议手动编写)//方法覆盖就是将继承过来的方法覆盖掉了public void move(){System.out.println("鸟在飞行!");}//子类抛出的异常不能比父类多/*public void move() {System.out.println("动物在移动!");}*///protected表示受保护的,没有public开放//错误:访问权限太低,/* protected void move(){System.out.println("鸟在飞");}*///没够构成方法覆盖//但是可以构成方法重载public void sing(){System.out.println("Bird singing");}}
class Cat extends Animal{public void move(){System.out.println("猫在走");}
}

注意事项

  • 注意1:方法覆盖只是针对于方法与属性无关
  • 注意2:私有方法无法覆盖
  • 注意3:构造方法不能被继承,所以构造方法也不能被覆盖
  • 注意4:方法覆盖只能针对于治理方法,静态方法没有覆盖意义

经典的案例

package Override;
//一个方法覆盖比较经典的案例
public class Test03 {public static void main(String[] args){//第一种方法/*Chinese c = new Chinese("中国人");c.speak();American a = new American("美国人");a.speak();*///第二种方法Chinese c = new Chinese();c.setName("中国人");c.speak();American a = new American();a.setName("美国人");a.speak();}
}
class People{private String name;public People() {}public People(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void speak(){System.out.println(name + "正在说话");}
}
class Chinese extends People{public Chinese(String name) {super(name);}public Chinese() {}public void speak(){//name为私有属性,只有调用grtName()才可以调用nameSystem.out.println(this.getName() + "说汉语");}
}
class American extends People{public American(String name) {super(name);}public American() {}public void speak(){//name为私有属性,只有调用grtName()才可以调用nameSystem.out.println(this.getName() + "说英语");}
}
package Override;
/*
关于Object中的toString()方法1.toString()方法的作用是什么?将java对象转换成字符串形式2.Object类中toSting()方法的默认实现是什么?public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}toSrting:意思是转换成String含义:调用一个Java对象的toString方法就可以将该Java对象转化成字符串形式。3.那么toString()方法给的默认实现够用么?*/
public class Test04 {public static void main(String[] args){MyDate t1 = new MyDate();//将对象转换为字符串形式//MyDate@776ec8df 是重写toString方法之前的结果//希望输出:xxxx年xx月xx日//1970年1月1日 重写之后的输出System.out.println(t1.toString());//当输出一个引用的时候,println方法会自动调用引用的toString方法System.out.println(t1);MyDate t2 =new MyDate(2000,8,7);System.out.println(t2.toString());System.out.println(t2);}
}
class MyDate{private int year;private int month;private int day;public MyDate() {//默认时间this(1970,1,1);}public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public int getMonth() {return month;}public int getDay() {return day;}public void setYear(int year) {this.year = year;}public void setMonth(int month) {this.month = month;}public void setDay(int day) {this.day = day;}public String toString() {return year + "年" + month + "月" + day + "日";}}

方法重载和方法覆盖有什么区别?

​ 方法重载发生在同一个类当中。

​ 方法覆盖是发生在具有继承关系的父子类之间。

​ 方法重载是一个类中,方法名相同,参数列表不同。

​ 方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致:
​ 方法名一致、参数列表一致、返回值类型一致。

多态

向上转型和向下转型的概念

第一个:向上转型
子 --> 父 (自动类型转换)
第二个:向下转型
父 --> 子 (强制类型转换,需要加强制类型转换符)
注意:
Java允许向上转型,也允许向下转型
无论是向上转型,还是向下转型
两种类型之间必须有继承关系,没有继承关系编译器报错

什么是多态?

多种状态
Java程序分为编译阶段和运行阶段
先来分析编译阶段:
对于编译器来说,编译器只知道a2的类型是Animal
所以编译器在编译的时候,会去Animal.class字节码文件中去找move方法,找到了绑定上move方法,编译成功,静态绑定成功
分析运行阶段:
运行阶段的时候,实际上在堆内存中存在的java对象是Cat对象,所以move的时候,真正参与move的对象是Cat,所以运行阶段会动态执行Cat对象的move()方法,这个过程属于运行阶段的绑定,属于动态绑定

多态表示多种形态:
编译的时候一种形态
运行的时候是一种形态。

向下转型的风险

会产生ClassCastException的错误

怎么避免:ClassCastException的产生
新的内容,运算符:instanceof

​ 第一:instanceof可以在运行阶段动态判断引用指向的对象的类型
​ 第二:引用instanceof的语法:
​ (引用instanceof类型)
​ 第三:instanceof运算符的运算结果只能是:true/fasle
​ 第四:c是一个引用,c变量保存了内存地址,指向了堆中的对象
​ 假设(c instanceof Cat)为True; 表示c内存中的java对象是一个Cat
​ 假设(c instanceof Cat)为false;表示c内存中的java对象不是一个Cat
​ instanceof在运行阶段动态判断。

​ 任何时候任何地点,在对类型进行向下转型时,一定要使用instanceof运算符,可以很好的避免ClassCastException

package duotai;
/*
多态的基础语法1.学习多态基础语法之前,我们需要普及两个概念:第一个:向上转型子 --> 父第二个:向下转型父 --> 子注意:Java允许向上转型,也允许向下转型无论是向上转型,还是向下转型两种类型之间必须有继承关系,没有继承关系编译器报错2.多态指的是:父类型引用指向子类的对象包括编译阶段和运行阶段编译阶段:绑定父类型的方法运行阶段:动态绑定子类型的方法3.什么时候使用向下转型?不要随便做强制类型转换子类对象中特有的方法,使用向下转型*/
public class Test01 {public static void main(String[] args){Animal a1 = new Animal();a1.move();Cat c1 = new Cat();c1.move();Bird b1 = new Bird();b1.move();/*1.Animal和Ca之间有继承关系2.Animal是父类,Animal是子类3.Cat is a Animal父类型的引用允许指向子类型的对象。Animal a2 = new Cat();a2就是父类型的引用new Cat()就是一个子类型的对象允许a2这个父类型引用指向子类型的对象。*/Animal a2 = new Cat();Animal a3 = new Bird();/*什么是多态? 多种状态Java程序分为编译阶段和运行阶段先来分析编译阶段:对于编译器来说,编译器只知道a2的类型是Animal所以编译器在编译的时候,会去Animal.class字节码文件中去找move方法,找到了绑定上move方法,编译成功,静态绑定成功分析运行阶段:运行阶段的时候,实际上在堆内存中存在的java对象是Cat对象,所以move的时候,真正参与move的对象是Cat所以运行阶段会动态执行Cat对象的move()方法,这个过程属于运行阶段的绑定,属于动态绑定多态表示多种形态:编译的时候一种形态运行的时候是一种形态。*/a2.move();a3.move();//====================================================================Animal a5 = new Cat();//分析程序一定要分析编译阶段和运行阶段的动态绑定//若调用CatchMouse就必须进行强制向下转型//因为a5是Animal类型,转成Cat,Animal和Cat之间存在继承关系,所以才没有报错Cat x = (Cat)a5;x.CatchMouse();//向下转型有风险吗Animal a6 = new Bird();//表面上a6是一个Animal,运行的时候实际上是Brid//运行阶段,堆内存实际上创建的是Bird对象,在实际运行中,Bird 对象转换成Cat对象,//bird和Cat对象之间没有继承关系/*  Cat y = (Cat)a6;y.CatchMouse();*///怎么避免:ClassCastException的产生/*新的内容,运算符:instanceof第一:instanceof可以在运行阶段动态判断引用指向的对象的类型第二:引用instanceof的语法:(引用instanceof类型)第三:instanceof运算符的运算结果只能是:true/fasle第四:c是一个引用,c变量保存了内存地址,指向了堆中的对象假设(c instanceof Cat)为True; 表示c内存中的java对象是一个Cat假设(c instanceof Cat)为false;表示c内存中的java对象不是一个Catinstanceof在运行阶段动态判断。任何时候任何地点,在对类型进行向下转型时,一定要使用instanceof运算符,可以很好的避免ClassCastException*/System.out.println(a6 instanceof Cat);if(a6 instanceof Cat){//如果a6为Cat则进行强制类型转换Cat y = (Cat)a6;y.CatchMouse();}}
}
class Animal{public void move(){System.out.println("moving");}
}
class Cat extends Animal{@Overridepublic void move() {System.out.println("Cat is Moving");}//除了move之外,应该有自己特有的行为public void CatchMouse(){System.out.println("catching");}
}
class Bird extends Animal{@Overridepublic void move() {System.out.println("Bird is flying");}public void Sing(){System.out.println("bird is singing");}
}
package duotai;
/*程序员可以观察到底层,到底是Bird和Cat进行instanceof判断是因为:在以后的开发中,程序员可能看不到*/
public class Test02 {public static void main(String[] args){Animal x = new Bird();Animal y = new Cat();if(x instanceof Bird){Bird a = (Bird)x;a.Sing();}else if(x instanceof Cat){Cat a = (Cat)x;a.CatchMouse();}if(y instanceof Cat){Cat b = (Cat)y;b.CatchMouse();}else if(y instanceof Bird){Bird b = (Bird)y;b.Sing();}}
}
package duotai;public class Test03 {public static void main(String[] args){//main程序员A负责编写Atest a = new Atest();a.test(new Cat());a.test(new Bird());}
}
class Atest{//程序员B负责编写//这个test()方法的参数是一个Animalpublic void test(Animal a){//你写的这个方法别人会调用//别人调用的时候可能给你test()方法传过来一个Bird//当然可能识别的//对于我来说,不知道调用的时候,会传给我什么参数if(a instanceof Cat){Cat c = (Cat) a;c.CatchMouse();}else if(a instanceof Bird){Bird b = (Bird) a;b.Sing();}}
}

多态在实际应用中的作用

降低程序的耦合度,提高程序的扩展力

public class Master{public void feed(Dog d){}public void feed(Cat c){}}以上的代码中表示:Master和Dog以及Cat的关系很紧密(耦合度高)。导致扩展力很差。public class Master{public void feed(Pet pet){pet.eat();}}以上的代表中表示:Master和Dog以及Cat的关系就脱离了,Master关注的是Pet类。这样Master和Dog以及Cat的耦合度就降低了,提高了软件的扩展性。

面向对象的三大特征:
封装、继承、多态

有了封装,有了这种整体的概念之后。
对象和对象之间产生了继承。
有了继承之后,才有了方法的覆盖和多态。

这里提到了一个软件开发原则:
七大原则最基本的原则:OCP(对扩展开放,对修改关闭)
目的是:降低程序耦合度,提高程序扩展力。
面向抽象编程,不建议面向具体编程。

package duotai;public class Test04 {public static void main(String[] args){Master m = new Master();Dog d = new Dog();Cats c = new Cats();YingWu y = new YingWu();m.feed(d);m.feed(c);m.feed(y);}}
class Master{public void feed(Pet p){//编译的时候,编译器发现p是一个pet类,会去Pet类中找eat()方法,结果找到了,编译器通过//运行的时候发现底层实际是Dog对象,就会自动调用Dog对象对应的eat方法上。p.eat();}}
class Pet{//这个方法可以不给具体的实现public void eat(){}}
class Dog extends Pet{public void eat(){System.out.println("dog eat");}
}
class Cats extends Pet{public void eat(){System.out.println("Cat eat");}}
class YingWu extends Pet{public void eat(){System.out.println("YingWu eat");}}

解释之前遗留的问题

私有方法无法覆盖。

方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。(这是因为方法覆盖通常和多态联合起来)

静态方法存在方法覆盖吗?

​ 多态自然就和对象有联系,而静态方法的执行不需要对象,
​ 所以一般情况下,我们会说静态方法不存在方法覆盖

总结两句话:
私有不能覆盖。
静态不谈覆盖。

在方法覆盖中,关于方法的返回值类型。

​ 什么条件满足之后,会构成方法的覆盖呢?
​ 1、发生具有继承关系的两个类之间。
​ 2、父类中的方法和子类重写之后的方法:
​ 具有相同的方法名、相同的形式参数列表、相同的返回值类型。

​ 学习了多态机制之后:
​ “相同的返回值类型”可以修改一下吗?
对于返回值类型是基本数据类型来说,必须一致。
​ 对于返回值类型是引用数据类型来说,重写之后返回值类型可以变的更小(但意义不大,实际开发中没人这样写。)。

super关键字

super是一个关键字,全部小写

super和this对比学

this:

​ this能出现在实例方法中和构造方法中
​ this语法是:“this.”、“this()”
​ this不能使用在静态方法中
​ this. 大部分情况下是可以省略的,在区分实例变量和局部变量的时候是不能省略的

​ this()只能出现在构造方法的第一行,通过当前的构造方法去调用“本类”中的其他方法,目的是:代码复用

super:

​ super能出现在实例方法中和构造方法中
​ super语法是:“super.”、“super()”
​ super不能使用在静态方法中
​ super. 大部分情况下是可以省略的,
​ super()只能出现在构造方法的第一行,通过当前的构造方法去调用“父类”中的其他方法,目的是:创建子类对象的时候先初始化父类型特征

super()

表示通过子类的构造方法调用父类的构造方法
模式现实世界中的这种场景:要想有儿子,需要现有父亲

super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。

重要的结论

当一个构造方法的第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法
所以必须保证父类的无参数构造方法是存在的

this()和super()不能共存,他们只能是都能存在构造方法第一行

无论怎么折腾,父类的无参数构造方法一定会执行的

package Super;
/*
1. super是一个关键字,全部小写
2. super和this对比学this:this能出现在实例方法中和构造方法中this语法是:“this.”、“this()”this不能使用在静态方法中this. 大部分情况下是可以省略的,在区分实例变量和局部变量的时候是不能省略的this()只能出现在构造方法的第一行,通过当前的构造方法去调用“本类”中的其他方法,目的是:代码复用super:super能出现在实例方法中和构造方法中super语法是:“super.”、“super()”super不能使用在静态方法中super. 大部分情况下是可以省略的,super()只能出现在构造方法的第一行,通过当前的构造方法去调用“父类”中的其他方法,目的是:创建子类对象的时候先初始化父类型特征
3. super()表示通过子类的构造方法调用父类的构造方法模式现实世界中的这种场景:要想有儿子,需要现有父亲
4. 重要的结论当一个构造方法的第一行:既没有this()又没有super()的话,默认会有一个super();表示通过当前子类的构造方法调用父类的无参数构造方法所以必须保证父类的无参数构造方法是存在的
5. this()和super()不能共存,他们只能是都能存在构造方法第一行
6. 无论怎么折腾,父类的无参数构造方法一定会执行的*/
public class Test01 {public static void main(String[] args){new B();/*A类的无参数构造方法实现B类的无参数构造方法实现*/}
}
class A{int i;public A(int i) {System.out.println("A类的有参数构造方法实现");}public A() {System.out.println("A类的无参数构造方法实现");}
/*一个类如果没有手动提供任何构造方法,系统会默认提供一个无参构造方法*/}
class B extends A{public B() {//调用父类中有参数的构造方法//super();//自动有的/*A类的无参数构造方法实现B类的无参数构造方法实现*/this("123");/*A类的无参数构造方法实现B类的有参数构造方法实现B类的无参数构造方法实现*/System.out.println("B类的无参数构造方法实现");}public B(String a){//super(); 默认有的 先调用/*A类的无参数构造方法实现B类的有参数构造方法实现B类的无参数构造方法实现*/System.out.println("B类的有参数构造方法实现");}
}

super和this的执行顺序

package Super;public class Test02 {public static void main(String[] args){new E();}}
class C{public C() {System.out.println("C 执行");}
}
class D extends C{public D() {System.out.println("D 执行");}public D(String name){System.out.println("D name");}
}
class E extends D {public E() {this("name");System.out.println("E 执行");}public E(String name) {this(name,20);System.out.println("E name 执行");}public E(String name,int i) {super(name);System.out.println("E name i 执行");}
}
//
C 执行
D name
E name i 执行
E name 执行
E 执行

super(实例参数)的使用时间

package Super;
/*
在恰当的时间使用super(实际参数列表):*/
public class Test03 {public static void main(String[] args){CreditAccount ca1 = new CreditAccount();System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit());CreditAccount ca2 = new CreditAccount("a",123,111);System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit());}
}
class Account{/*私有的方法只能在本类中访问*/private String actno; //账号private double balance; //余额public Account() {}public Account(String actno, double balance) {this.actno = actno;this.balance = balance;}public String getActno() {return actno;}public double getBalance() {return balance;}public void setActno(String actno) {this.actno = actno;}public void setBalance(double balance) {this.balance = balance;}
}
//其他类型的账户:信用卡账户
class CreditAccount extends Account{private double credit;public CreditAccount(String actno, double balance, double credit) {/*this.actno = actno;this.balance = balance;以上两行代码在恰当的位置,正好可以使用:super(actno)通过子类的构造方法调用父类的构造方法*/super(actno,balance);this.credit = credit;}public CreditAccount() {}public void setCredit(double credit) {this.credit = credit;}public double getCredit() {return credit;}
}
null,0.0,0.0
a,123.0,111.0

super执行的内存图

注意:虽然调用构造方法,在构造方法执行的过程中还调用了一连串的父类的构造方法,父类构造方法又继续调用了它的父类构造方法,但是实际上对象只创建了一个

“super(实参)”到底是干嘛的?

super(实参):初始化当前对象的父类型特征,并不是创建新对象,实际上对象只能创建出一个

super关键字代表什么?

​ super关键字代表的就是“当前对象”的那部分父类型特征

例子

子类型和父类型无同名属性

package Super;public class Test04 {public static void main(String[] args){Vip v = new Vip("z");v.Shopping();}
}
class Cumstor{String name;public Cumstor() {}public Cumstor(String name) {this.name = name;}public void Shopping(){}
}
class Vip extends Cumstor{public Vip() {}public Vip(String name) {super(name);}public void Shopping(){System.out.println(this.name + "shopping");System.out.println(super.name + "shopping");System.out.println(name + "shopping");}
}
zshopping
zshopping
zshopping

子类型和父类型有同名属性

package Super;
/*this.和super.在大部分的情况下都是可以省略的this.在区分局部变量和实例变量的时候不可以省略super.父类中这个属性,子类中也有这个属性,想在子类型中访问父类型中的属性,就不可以省略*/
public class Test05 {public static void main(String[] args){Vip v = new Vip("z");v.Shopping();}
}class Cumstor{String name;public Cumstor() {}public Cumstor(String name) {this.name = name;}public void Shopping(){}
}
class Vip extends Cumstor{//假设子类也有一个同名属性String name;public Vip() {}public Vip(String name) {super(name);}//super和this都不能再静态方法中出现public void Shopping(){//this表示当前空间System.out.println(this.name + "shopping");//super表示当前对象的父类型特征(super是this指向的那个对象中的一块空间)System.out.println(super.name + "shopping");System.out.println(name + "shopping");}
}
//
nullshopping
zshopping
nullshopping

super和this都不能再静态方法中出现

java如何区分子类属性和父类型属性

this.和super.在大部分的情况下都是可以省略的
this.在区分局部变量和实例变量的时候不可以省略
super.父类中这个属性,子类中也有这个属性,想在子类型中访问父类型中的属性,就不可以省略

super不能单独使用

super不是引用,super不保存内存地址,super也不指向任何对象
super只是代表当前对象内部的父类型特征

package Super;
/*通过测试得出的结论。super不是引用,super不保存内存地址,super也不指向任何对象super只是代表当前对象内部的父类型特征*/
public class Test06 {public void doSome(){//输出引用的话,会自动调用引用的toSting方法System.out.println(this);//System.out.println(this.toString());//错误需要'.'System.out.println(super.);}public static void main(String[] args){Test06 t = new Test06();t.doSome();}
}
package Super;public class Test07 {public static void main(String[] args){Cat c = new Cat();c.M();}
}
class Animal{public void move(){System.out.println("Animal move");}
}
class Cat extends  Animal{public void move(){System.out.println("Cat move");}public void M(){this.move();move();super.move();}
}
  • super.属性 - 访问父类的属性
  • super.方法名(实参) - 访问父类的方法
  • super.(实参) - 访问父类的构造方法

super执行的内存图

注意:虽然调用构造方法,在构造方法执行的过程中还调用了一连串的父类的构造方法,父类构造方法又继续调用了它的父类构造方法,但是实际上对象只创建了一个

[外链图片转存中…(img-L7U7fMuh-1634040754692)]

“super(实参)”到底是干嘛的?

super(实参):初始化当前对象的父类型特征,并不是创建新对象,实际上对象只能创建出一个

super关键字代表什么?

​ super关键字代表的就是“当前对象”的那部分父类型特征

例子

子类型和父类型无同名属性

package Super;public class Test04 {public static void main(String[] args){Vip v = new Vip("z");v.Shopping();}
}
class Cumstor{String name;public Cumstor() {}public Cumstor(String name) {this.name = name;}public void Shopping(){}
}
class Vip extends Cumstor{public Vip() {}public Vip(String name) {super(name);}public void Shopping(){System.out.println(this.name + "shopping");System.out.println(super.name + "shopping");System.out.println(name + "shopping");}
}
zshopping
zshopping
zshopping

[外链图片转存中…(img-0aZuJNxt-1634040754692)]

子类型和父类型有同名属性

package Super;
/*this.和super.在大部分的情况下都是可以省略的this.在区分局部变量和实例变量的时候不可以省略super.父类中这个属性,子类中也有这个属性,想在子类型中访问父类型中的属性,就不可以省略*/
public class Test05 {public static void main(String[] args){Vip v = new Vip("z");v.Shopping();}
}class Cumstor{String name;public Cumstor() {}public Cumstor(String name) {this.name = name;}public void Shopping(){}
}
class Vip extends Cumstor{//假设子类也有一个同名属性String name;public Vip() {}public Vip(String name) {super(name);}//super和this都不能再静态方法中出现public void Shopping(){//this表示当前空间System.out.println(this.name + "shopping");//super表示当前对象的父类型特征(super是this指向的那个对象中的一块空间)System.out.println(super.name + "shopping");System.out.println(name + "shopping");}
}
//
nullshopping
zshopping
nullshopping

[外链图片转存中…(img-LhaJ8N99-1634040754693)]

super和this都不能再静态方法中出现

java如何区分子类属性和父类型属性

this.和super.在大部分的情况下都是可以省略的
this.在区分局部变量和实例变量的时候不可以省略
super.父类中这个属性,子类中也有这个属性,想在子类型中访问父类型中的属性,就不可以省略

super不能单独使用

super不是引用,super不保存内存地址,super也不指向任何对象
super只是代表当前对象内部的父类型特征

package Super;
/*通过测试得出的结论。super不是引用,super不保存内存地址,super也不指向任何对象super只是代表当前对象内部的父类型特征*/
public class Test06 {public void doSome(){//输出引用的话,会自动调用引用的toSting方法System.out.println(this);//System.out.println(this.toString());//错误需要'.'System.out.println(super.);}public static void main(String[] args){Test06 t = new Test06();t.doSome();}
}
package Super;public class Test07 {public static void main(String[] args){Cat c = new Cat();c.M();}
}
class Animal{public void move(){System.out.println("Animal move");}
}
class Cat extends  Animal{public void move(){System.out.println("Cat move");}public void M(){this.move();move();super.move();}
}
  • super.属性 - 访问父类的属性
  • super.方法名(实参) - 访问父类的方法
  • super.(实参) - 访问父类的构造方法

(超详细笔记整理)动力节点_老杜 | JavaSE零基础 :P329(方法) - P479相关推荐

  1. Python后端转JAVA最快多久_【动力节点】老杜支招:Java小白学习入门攻略,涵盖学习路线...

    动力节点在B站的直播相当好,相当受欢迎,教学总监亲自解惑.零基础学Java的同学确实把思路打开不少. 回顾:11月14日晚8:00,杜老师在动力节点B站大咖直播间,首次开播与粉丝面基,本场直播不吹,不 ...

  2. JavaScript零基础入门--笔记动力节点最新老杜(九-完结)全套笔记精髓

    JSON         1.什么是JSON,有什么用?                     JavaScript Object Notation(JavaScript对象标记),简称JSON.( ...

  3. 学习javascript这一篇就够了超详细笔记(建议收藏)上

    学习javascript这一篇就够了超详细笔记(建议收藏)上 1.初识 计算机基础导读 编程语言 计算机基础 初识js 浏览器执行 js组成 js初体验-三种书写位置 js注释 js输入输出语句 2. ...

  4. Java并发编程(中下篇)从入门到深入 超详细笔记

    接上一篇博客笔记:Java并发编程(中上篇)从入门到深入 超详细笔记_未来很长,别只看眼前的博客-CSDN博客https://blog.csdn.net/weixin_53142722/article ...

  5. SPRING注解驱动开发-雷神课程超详细笔记

    SPRING注解驱动开发-雷神课程超详细笔记 时间:2021-03-21 2022-04-06更新:最近翻起一年多前写的笔记复习,还是收获颇多,很多当时无法理解的知识现在慢慢能理解了,可能是工作一年的 ...

  6. 清晰易懂!关于PS入门的超详细笔记!

    给大家分享一篇关于PS入门的超详细笔记!原理讲解清晰明了,虽不是新版本解析,但都是新手学习PS必掌懂的一些知识点,灰常的实用,转走收藏学习! 编辑:千锋UI设计 来源:PS学堂

  7. el-select 多选取值_数值优化|笔记整理(3)——线搜索中的步长选取方法,线性共轭梯度法...

    上一节笔记传送门: 学弱猹:数值优化|笔记整理(2)--线搜索:步长选取条件的收敛性​zhuanlan.zhihu.com ------------------------------------ 大 ...

  8. 回溯法采用的搜索策略_数值优化|笔记整理(3)——线搜索中的步长选取方法,线性共轭梯度法...

    上一节笔记传送门: 学弱猹:数值优化|笔记整理(2)--线搜索:步长选取条件的收敛性​zhuanlan.zhihu.com ------------------------------------ 大 ...

  9. SpringBoot学习笔记总结——动力节点

    最近跟着动力节点王鹤老师的视频学到了springboot,看过最细的springboot讲解,初学入门最佳,自己做了笔记分享给大家 视频资源: 动力节点springboot视频教程-专为springb ...

最新文章

  1. data.DataLoader 数据丢失 不能复用
  2. Silverlight专题(WatermarkedTextBox使用)--摘录 很受用
  3. java form 上传文件_JAVA入门[16]-form表单,上传文件
  4. osgdem的参数表(转)
  5. C语言试题二十九之编写函数int function(int lim,int aa[max])求出小于或等于lim的所有素数并放在aa数组中,该函数返回所求的素数的个数。
  6. python学习第22天
  7. ios 旋转屏幕试图切换_iOS增强现实应用(AR)设计指南(上)
  8. IIS7 设置 UrlRewrite
  9. 【Android进阶】Junit单元測试环境搭建以及简单有用
  10. html 圆圈项目符号,html – 列表项下的项目符号
  11. 参数展示初始三层架构
  12. 龙芯指令集也可以开源
  13. 20191123每日一句
  14. linux中cron表达式指南
  15. 计算机未安装flash,win10系统提示未安装Flash的解决方法
  16. VS2017各版本区别
  17. Python中main函数
  18. MATLAB的变换器毕业设计,基于matlab的反激变换器分析与设计毕业设计doc.docx
  19. 数据库常用字段、列属性、表类型与SQLyog工具的使用
  20. 滤镜怎么调好看?分享给图片调色的教程

热门文章

  1. K-anonymity 2-anonymous
  2. 架构的演进,阿里资深Java工程师表述架构的腐化之谜
  3. 南京市政府昨与西门子签署战略合作协议
  4. 辽宁启迪电商:拼多多推荐词优化升级怎么做?
  5. kafka的auto.offset.reset详解与测试
  6. 开源项目:完整的电商系统,直接拿来用!
  7. SEO、网站优化、搜索引擎优化、首选夏易网络
  8. 密码学 aes rsa 分段加密 填充 rsakey 生成
  9. 通过现实生活中一个例子来理解 JavaScript Promise
  10. m4枪 maya_攻防世界--The_Maya_Society