1. Idea 软件
创建包: 在scr下面 :右键--------->new(新建)---------->Package(包)
创建一个类: 选中包名------->右键------->new---------->Java Class (java文件名称和类名称自动一致)
快捷键:
Alt + Insert 代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等
main+enter main方法
sout+enter 输出语句
2. static 关键字
1) static 基本的概念: 共享,共用 (可以被多个对象共用!)
-
被静态修饰的东西是随着类的加载而加载
-
优先于对象存在
-
可以通过类名调用
2)static关键字的特点:
-
被静态修饰的变量/方法,都是随着类的加载而加载!!!
-
优先于对象存在,不能和this关键字共存,this是需要等待对象被创建完毕,而被静态修饰的,优先进了static内存区了
-
共享,共用(可以被多个对象共用)
举例:
水杯中的水,不能被共用(大家口味不一样)
饮水机中的水, 可以被共用
-
被静态修饰的变量/方法,推荐使用的类名访问!!!
-
如果是静态的成员变量:
类名.变量名;
-
如果是静态的成员方法:
类名.方法名();
-
3) 静态的使用过程中的注意事项:
-
非静态的成员方法:可以访问静态的成员变量或者是非静态的成员变量;
-
静态的成员方法: 只能访问静态的方法或者静态的成员变量...
-
简单记:静态永远只能访问静态!
3. 制作工具类 ArrayTools
自定义的ArrayTool类 工具类: 1)无参构造私有化 2)对外提供公共的静态方法,直接通过类名访问
现在使用ArrayTool:自定义数组工具类,里面提供静态功能,每一个功能加入文档注释 它可以被解析 如何通过刚才写的文档注释给ArrayTool类产生文档说明书 1)将ArrayTool这个类 的内容复制到一个java文件中(不需要包),使用dos控制台来使用 2)进入dos控制台,找到当前文件的内容(.java) ArrayTool.java 3)使用命令: javadoc -d 目录名称 -author -version ArrayTool.java(java文件)
-
面试题 Student s = new Student() ;完成了哪些事情
初始化过程: 1)在栈内存中开辟空间 Student s,变量s开辟 2)new Student(),需要在堆内存中申请空间 3)在申请空间的同时,需要对成员变量,进行默认初始化(根据数据类型进行默认赋值) int类型默认0,String类型默认null 4)当默认初始化完毕,申请空间完毕,产生堆内存空间地址 5)通过构造方法初始化 6)将堆内存空间地址值赋值给栈内存的变量s 7)栈内存的变量s指向堆内存地址 8)当对象整个完毕之后,等待垃圾回收器空闲时候回收不用的对象...
4. 代码块
-
代码块的含义:
使用{}包裹起来的称为"代码块"
-
分类:
1) 局部代码块:
{}: 在局部位置(方法定义中定义)
作用:限定局部变量的生命周期
2) 构造代码块:
{} : 在构造方法之前(类的成员位置)
特点: 在执行构造方法之前,如果存在构造代码块,优先执行构造代码块,然后才是构造方法!
作用: 将构造方法中初始化的过程,可以在构造代码块中使用(一般开发中很少,一些笔试题出现,考点:考的就是构造代码块和构造方法之前)
3) 静态代码块----->应用场景:jdbc中就会使用到...
特点: 随着类的加载而加载,优先于对象存在
static{
}
-
静态代码块只执行一次,因为类就加载一次! (考点)
-
优先级: (考点) : 静态代码块 > 构造代码块 > 构造方法
5. 继承
5.1 继承的概念:
将多个类的共性内容抽取出来,放在一个独立类中,让这个独立的类和这多个类产生一种关系 "继承"
格式: class 子类名 extends 父类名 }
5.2 继承的好处:
1)提高了代码复用性 多个类相同的成员可以放到同一个类中 2)提高了代码的维护性 如果功能的代码需要修改,修改一处即可 3)类与类产生的这种关系"继承",是多态的前提条件! 其实这也是继承的一个弊端:类的耦合性很强
5.3 继承的弊端:
因为存在关系,类与类之间就存在耦合性! 开发的设计原则: 低耦合,高内聚
耦合:类与类之间的关系 低耦合:关系越简单越好,否则.如果继承关系的多,一个父类的存在问题,其他类出现问题! 内聚:指的是执行某件事情的能力!一个类能解决的尽量使用一个类完成
5.4 继承的特点:
1)在Java语言中,类与类之间的继承关系,只支持单继承 class Zi extends Fu1,Fu2{}... (Java中不支持类和类之间多继承)
2)虽然类与类之间只支持单继承,但是可以多层继承
//举例 //使用继承概念之后的写法 //抽象一个父类: Person class Person{ //吃 public void eat(){ System.out.println("饿了就需要吃饭..."); } //睡 public void sleep(){ System.out.println("困了就需要休息..."); } //玩 public void play(){ System.out.println("学习困了就需要劳逸结合..."); } } //子类:学生类 class Student extends Person{ //特有功能 public void study(){ System.out.println("学习JavaEE..."); } } //子类:老师类 class Teacher extends Person{ public void teach(){ System.out.println("讲解JavaEE..."); } } //子类:程序员类 class Programmer extends Person{ public void code(){ System.out.println("日日夜夜coding..."); } } //测试类 public class ExtendsDemo1 { public static void main(String[] args) { //没有使用继承之前的测试: //创建学生类对象 Student s = new Student() ; s.eat() ; s.sleep() ; s.play() ; s.study(); //特有功能 System.out.println("------------------------------------------"); //创建老师类对象 Teacher t = new Teacher() ; t.eat(); t.sleep(); t.play(); t.teach();//特有功能 System.out.println("------------------------------------------"); //创建程序员类 Programmer programmer = new Programmer() ; programmer.eat(); programmer.sleep(); programmer.play(); programmer.code(); //特有功能 } }
5.5 最基本的注意事项:
1) 子类继承父类,只能继承父类非私有的成员,私有的成员可以间接通过公共访问访问!
因为私有成员,只能在本类访问,外界类不能访问!
2) 子类继承父类,不能继承父类的构造方法,但是可以通过super访问(super重点关键字)
//举例: //父类 class Fu{ //父类有两个成员:公共的/私有的 public int num = 40 ; private int num2 = 100 ; //提供一个公共的成员方法 public void method(){ System.out.println(num2); } //私有的成员方法 private void function(){ System.out.println("function Fu..."); } //公共的方法 public void function2(){ function(); } } //子类 class Zi extends Fu{ //定义一个成员方法 public void show(){ //展示数据 System.out.println(num); // System.out.println(num2);//num2变量私有的 } } //测试类 public class ExtendsDemo1 { public static void main(String[] args) { //创建子类对象 Zi z = new Zi() ; z.show() ; z.method(); //z.function() ;//function方法 private 修饰了 z.function2(); } }
5.6 继承中类成员的访问问题
1) 成员变量的访问问题:
情况1: 子类继承父类,子类的成员变量名称和父类的成员变量名称不一致的情况:很简单,分别调用即可! 情况2: 子类继承父类,子类的成员变量名称和父类的成员变量名称一致的情况: 一句话:遵循 "就近原则" 1)现在子类的局部位置中找,如果存在,就使用 2)如果不存在,那么就在子类的成员位置中找,如果存在,就使用 3)如果子类的成员位置中不存在,那么就在父类的成员位置中找,如果存在,就使用; 4)如果父类的成员位置中不存在,那么就报错了,压根不存在这个变量
//定义一个父类 class Fu{ //父类的成员变量 int num = 100 ; } //定义一个子类 class Zi extends Fu{ // 情况2:子类的成员变量名称和父类的成员变量名称一致 // int num = 200 ; // 情况1:子类的成员变量名称和父类的成员变量名称不一致 int num2 = 200 ; //成员方法 public void show(){ //子类的局部位置 int num = 30 ; System.out.println(num) ; // System.out.println(num2); } } //测试类 public class ExtendsDemo { public static void main(String[] args) { //创建子类对象 //情况2: /* Zi zi = new Zi() ; System.out.println(zi.num); //System.out.println(zi.num2); System.out.println("-----------------------------------"); zi.show();*/ //情况1: //创建子类对象 Zi zi = new Z() ; zi.show() ; } }
2) 构造方法的访问问题:
子类继承父类,不能继承父类的构造方法,但是可以通过super访问(super重点关键字)!!! 如何访问: 子类的所有构造方法都要(默认)访问父类的无参构造方法 因为存在继承关系,子类的构造方法可能会用到父类的数据,所以需要让父类先初始化(构造方法),然后子类在进行初始化 ---->分层初始化 在子类的所有构造方法中第一句话:super() ; 访问父类的无参构造方法!!!
//举例 //定义一个父类 class Fu { //先提供父类的无参构造方法 public Fu(){ System.out.println("Fu的无参构造方法...") ; } } //定义一个子类 class Zi extends Fu{ //子类的无参构造方法 public Zi(){ //super(); //可以省略不写,默认的! System.out.println("Zi的无参构造方法...") ; } //提供子类的有参构造方法 public Zi(String name){ //super() ;可以省略不写,默认的! System.out.println("Zi的有参构造方法..."); } } //测试类 public class ExtendsDemo1{ public static void main(String[] args) { //创建子类对象 Zi zi = new Zi() ; System.out.println("----------------------------") ; Zi zi2 = new Zi("hello") ; } }
面试题: 子类继承父类,如果父类的无参构造方法没有提供,仅仅提供父类的有参构造方法,子类会出现什么现象,如何解决呢? 子类的所有构造方法都会报错,原因就是没有父类的无参构造方法, 子类的所有构造方法默认访问父类的无参构造方法(super();) 解决方案: 1)最简单的方式:给父类提供出无参构造方法 2)现在不想让你父类的无参构造方法 可以让子类的所有构造方法直接访问父类的有参方法... 3)很少用到: 方式3: 先通过子类的有参构造方法,访问本类的无参构造方法 this() 然后通过本类的无参构造方法,访问父类的有参构造方法,让其初始化(子类的所有构造方法只要一个能够让父类初始化)
5.7 this 和 super的区别
区别 super:代表父类的空间标识(父类对象的地址值引用) this:代表当前本类的对象的地址值引用 访问区别 访问成员变量: this.变量名 :访问当前类的成员变量 super.变量名:访问的父类的成员变量 访问构造方法: this() :访问当前类的无参构造方法 super(): 访问的是父类的无参构造方法 this(xx): 访问的是当前类的有参构造方法 super(xx): 访问的是父类的有参构造方法 访问成员方法 this.方法名() : 访问的是当前类的成员方法 super.方法名():访问的是父类的成员方法
-
难点:
1)继承的关系中的构造方法的访问问题: 子类的构造方法默认父类的无参构造方法,优先要让父类先初始化;只要存在继承关系,就需要分层初始化(先父,在子) 2) 代码块的优先级 静态代码块>构造代码块>构造方法 即使存在继承关系: 子父类中都存在静态代码块---->先执行父类的静态,然后子类的静态
5.8 方法重写和方法重载
方法重写: 子类继承父类的时候,子类的出现了和父类一模一样的方法声明,这个子类的功能将父类的功能覆盖掉,使用自己的业务功能完成! 英文单词:override 方法重载:overload:多个方法名相同,形式参数列表不同,与返回值无关,目的:为了提高功能扩展! 方法重写(覆盖/复写):override:子类继承父类的时候,子类的出现了和父类一模一样的方法声明 目的:使用子类的功能,将父类的功能覆盖掉
5.9 final关键字
final:最终的,无法更改的(状态修饰符) 特点: 1)可以修饰类,该类不能被继承,它不能在进行扩展了... 举例:后面常用类中重要的类String:被final修饰 2)可以修饰变量,此时这个变量是一个常量:自定义常量 3)可以修饰成员方法,此时这个方法不能被重写 final的应用场景 (扩展) 自定义常量使用居多; final会结合static一块使用(static修饰:可以类名直接调用) public static final int num = 100 ; //修饰基本数据类型:编译时期常量 (Jvm不需要加载) //Integer:int类型的包装类类型(引用类型) public static final Integer i = new Integer() ;//修饰的引用数据类型 :运行时期常量(JVM需要加载类)
*final修饰的基本数据类型和修饰引用数据类型的区别? 1)修饰的基本数据类型:基本数据类型的值不能在改变,只能赋值一次,不能在赋值了! 此时这种常量,称为"编译时期常量",Jvm只是检查语法,不需要加载的! 2)修饰的引用数据类型:引用数据类型的空间地址值不能在改变,但是里面的成员变量(没有加入final),依然可以访问 这种常量,Jvm加载引用数据类型,属于"运行时期常量"! 开发中使用最多的: 就是修饰基本数据类型: 传统方式的自定义常量 public static final 基本数据类型 变量名 = 常量值 ; JDK5以后:枚举类 Enum :定义常量
/**举例: * 看程序,写结果 * 考点: * 继承中构造对象的过程----->分层初始化 */ class ClassA{ public ClassA(){ System.out.println("ClassA()"); } } class ClassB{ public ClassB(){ System.out.println("ClassB()"); } } class ClassC extends ClassA{ public ClassC(){ System.out.println("ClassC()"); } } class ClassD extends ClassB{ private ClassA ca = new ClassA(); //创建ClassA private ClassC cc; public ClassD(){ System.out.println("ClassD()"); } public ClassD(int i){ cc = new ClassC(); System.out.println("ClassD(int)"); } } public class TestConstructors{ public static void main(String args[]){ // ClassD cd1 = new ClassD(); /** * ClassB() * ClassA() * ClassD() */ ClassD cd2 = new ClassD(10); /** * ClassB() * ClassA() * ClassA() * ClassC() * ClassD(int) */ } }