自学Java基础知识第八天

day08

1. 继承

1.1 继承中的成员变量

1. 子类可以继承到父类中所有非私有成员变量, 继承到了可以直接使用

2. 如果子类定义出了与父类同名的成员变量

  a : 在子类中,使用子父类重名成员变量时, 根据变量就近访问原则, 优先使用子类中定义的成员变量;

  变量就近访问原则 : 如果有局部变, 优先使用局部变量; 没有局部变量, 优先使用本类成员变量; 没有本类成员变量, 再使用父类中的可继承成员变量...

  b : 在子类中, 想要使用父类中的成员变量, 使用super关键字

   super : 表示当前类型对象的父类引用

   super.i; // 父类成员变量i的使用

代码

package com.ujiuye.extendsdemo;

public class Fu {

int i = 10;

int j = 20;

}

package com.ujiuye.extendsdemo;

public class Zi extends Fu {

   // 1. Zi类继承到了父类中成员 i j

// Zi类中定义了与父类同名成员i

int i = 99;

// useVariable功能 : 使用子父类中的成员变量

public void useVariable(int i) {

// 参数列表上局部变量i使用

System.out.println(i);

// Zi类成员变量i

System.out.println(this.i);

// Fu类成员变量i

System.out.println(super.i);

}

}

package com.ujiuye.extendsdemo;

public class TestFuAndZi {

public static void main(String[] args) {

Zi z = new Zi();

z.useVariable(100);

}

}

1.2 thissuper关键字在内存中的理解

1. 子类的.class字节码文件进入方法区之前, 父类的.class字节码文件要优先于子类进入到方法区中

2. 当创建子类对象时, 要先在子类的堆内存空间区域中开辟出父类的成员内存空间, 保证父类先进入到内存将一切可继承的成员准备好, 子类才可以直接继承使用; 接下来子类成员进内存

 

1.3 继承中的成员方法

1. 子类可以继承到父类中所有非私有成员方法功能, 继承到了可以直接使用

2. 如果子类认为从父类继承来的方法功能, 不能满足子类需求, 可以重写从父类继承来的方法功能, 通常重写是为了让方法越来越好

   子类重写父类继承来的方法功能要求:

1) 方法的返回值类型, 方法名, 参数列表与父类方法保持一致

2) 方法修饰符方面, 子类重写的方法修饰符范围大于等于父类修饰范围

   public公共---->默认修饰------>private

   如果类, 方法, 成员变量, 没有任何权限修饰, 那就是默认修饰, 默认修饰不写出来

3) 在子类重写方法之上, 使用注解 @Override 验证方法是否是重写方法

注意 : 子类重写方法之后, 优先使用子类重写方法功能

  1. 如果在子类已经重写父类某方法前提下, 想要调用父类的同名方法功能, 使用super关键字, super.方法名(实际参数);

  

代码

package com.ujiuye.extendsdemo;

public class Fu {

int i = 10;

int j = 20;

public void fun() {

System.out.println("父类---fun");

}

public int getSum(int x, int y) {

return x + y;

}

}

package com.ujiuye.extendsdemo;

public class Zi extends Fu {

   // 1. Zi类继承到了父类中成员 i j

// Zi类中定义了与父类同名成员i

int i = 99;

// useVariable功能 : 使用子父类中的成员变量

public void useVariable(int i) {

// 参数列表上局部变量i使用

System.out.println(i);

// Zi类成员变量i

System.out.println(this.i);

// Fu类成员变量i

System.out.println(super.i);

}

// 2. Zi类继承到了父类中方法fun, getSum

@Override

public void fun() {

System.out.println("子类---fun");

// 调用父类fun方法

super.fun();

}

}

package com.ujiuye.extendsdemo;

public class TestFuAndZi {

public static void main(String[] args) {

// 1. 成员变量测试

Zi z = new Zi();

z.useVariable(100);

System.out.println(z.j);// 20

// 2. 方法测试

z.fun();// 调用子类重写方法

int sum = z.getSum(3, 5);// 调用从父类继承来的方法功能

System.out.println(sum);

}

}

1.4 继承中的构造方法

1. 父类的构造方法子类无法继承, 子类构造方法中可以调用父类构造, 一定调用

2. 继承中的构造:

  1) 子类构造方法方法第一行,如果没有手动调用任何构造, 那么系统会自动(默认)调用父类的空参数构造方法, 调用super();

  2) 子类构造方法第一行手动调用构造, 系统不会再自动添加父类构造调用

注意:

  1. super() 必须在子类构造的有效行第一行, 保证父类成员优先于子类进堆内存
  2. this() 必须在构造有效行第一行, 间接保证父类成员优先于子类进堆内存
  3. super() this() 都必须在构造有效行第一行, 二选一

代码

package com.ujiuye.extendsdemo;

public class Fu {

int i = 10;

int j = 20;

public void fun() {

System.out.println("父类---fun");

}

public int getSum(int x, int y) {

return x + y;

}

// 定义出一个空参数父类构造

public Fu() {

System.out.println("我是父类构造");

}

public Fu(int i) {

this.i = i;

}

}

package com.ujiuye.extendsdemo;

public class Zi extends Fu {

   // 1. Zi类继承到了父类中成员 i j

// Zi类中定义了与父类同名成员i

int i = 99;

// useVariable功能 : 使用子父类中的成员变量

public void useVariable(int i) {

// 参数列表上局部变量i使用

System.out.println(i);

// Zi类成员变量i

System.out.println(this.i);

// Fu类成员变量i

System.out.println(super.i);

}

// 2. Zi类继承到了父类中方法fun, getSum

@Override

public void fun() {

System.out.println("子类---fun");

// 调用父类fun方法

super.fun();

}

// 3. 继承中构造

public Zi() {

// 父类构造调用

// super();

super(2000);

}

public Zi(String s) {

// 手动调用本类构造,本类构造第一行还是父类构造调用

        // this() 在第一行也是为了保证父类成员优先于子类进内存

this();

}

}

package com.ujiuye.extendsdemo;

public class TestFuAndZi {

public static void main(String[] args) {

// 1. 成员变量测试

Zi z = new Zi();

z.useVariable(100);

System.out.println(z.j);// 20

// 2. 方法测试

z.fun();// 调用子类重写方法

int sum = z.getSum(3, 5);// 调用从父类继承来的方法功能

System.out.println(sum);

}

}

1.5 thissuper关键字的使用总结

1. this关键字 :

  a : 区分成员变量和局部变量重名问题, 带有this.关键字表示成员变量的使用

  b : 本类构造方法之间调用, this(被调用构造实际参数);

  1. super关键字:

  a : 区分子类与父类中重名成员变量和方法功能, 带有super.关键字表示父类的成员变量或者方法功能使用

  b : 子类构造方法第一行super(被调用父类构造实际参数); 调用父类构造

注意 : 在构造方法调用场景下, this() 或者 super() , 两者都必须在构造方法有效行第一行, 因此两者的调用二选一

2. 代码块(了解)

2.1代码块的介绍

1. 代码块 : 表示将代码放置到一对大括号中, 将代码块放置位置不同, 作用效果和运行机制就会不同

2. 代码块分类:

  1) 局部代码块

  2) 构造代码块

  3) 静态代码块(掌握)

  4) 同步代码块(多线程再讲解)

2.2 局部代码块

1. 格式: 使用一对大括号包裹代码

2. 位置 : 定义在方法中

3. 作用:

   1) 为了限定变量作用范围, 定义在局部代码块中的变量, 只能在局部代码块中使用, 出了局部代码块,不能再继续使用

   2) 如果一个变量不能再使用, 那么这个变量所占有的内存空间就会变成垃圾, 等待JVM虚拟机进行空间回收, 变相节省内存空间

4.注意事项:

   局部代码块之外定义的变量, 如果在局部代码块中进行修改, 出了局部之外, 修改仍然生效, 因此局部代码块之外定义的变量, 不受局部代码块限制

代码

package com.ujiuye.block;

public class Demo01_局部代码块 {

public static void main(String[] args) {

int j = 20;

// 定义出局部代码块

{

// 因为变量i定义在局部代码块中, 因此i的使用范围只能在局部代码块中

// 出了布局代码块, i变量不能使用

int i = 10;

System.out.println(i);

j = 99;

}

//i cannot be resolved to a variable

// System.out.println(i); i变量超出了最大使用范围

System.out.println(j);// 99

}

}

2.3 构造代码块

1. 格式 : 使用一对大括号包裹代码

2. 位置 : 定义在类中方法外

3. 构造代码块运行机制:

   每次创建对象时, JVM虚拟机主动调用一次构造代码块, 构造代码块在构造方式之前运行

4.作用 :

   1) 可以为对象中的成员变量进行赋值

   2) 因为构造代码块在构造方法之前运行, 因此如果多个构造方法有相同代码处理逻辑, 可以将相同逻辑提升到构造代码块中运行

代码

package com.ujiuye.block;

public class Demo02_构造代码块 {

int i;

int j;

// 构造代码块

{

// 1. 给成员变量进行赋值

i = 10;

j = 20;

System.out.println("我是代码块");

// 2. 因为构造代码块在构造方法之前运行, 因此如果多个构造方法有相同代码处理逻辑, 可以将相同逻辑提升到构造代码块中运行

System.out.println("我是构造");

}

public Demo02_构造代码块() {

//System.out.println("我是构造");

}

public Demo02_构造代码块(int i,int j) {

this.i = i;

this.j = j;

//System.out.println("我是构造");

}

public static void main(String[] args) {

Demo02_构造代码块 demo = new Demo02_构造代码块();

System.out.println(demo.i);

System.out.println(demo.j);

Demo02_构造代码块 demo1 = new Demo02_构造代码块();

}

}

2.4 静态代码块(掌握)

  1. 格式: 使用一对大括号包裹代码, 在大括号外使用static 关键字标识静态代码块

   static{

  

}

  1. 位置 : 定义在类中方法外
  2. 执行机制:

     静态属于类, 静态代码块也属于类, 当类型的.class字节码文件加载进入方法区, 静态成员需要加载到静态区域中, 静态代码块会由JVM虚拟机调用执行, 静态代码块只随着类的加载运行一次

  1. 作用:

1) 可以为类型中的静态成员变量进行赋值

2) 如果类中有一进入内存就需要马上运行的代码, 可以设计在静态代码块中, 例如 : 驱动的加载, 交易中人民币与其他币种的汇率兑换, 在执行交易之前, 汇率要先准备好, 才能保证交易的正常运作, 且汇率兑换比率执行一次就可以

   

代码

package com.ujiuye.block;

public class Demo03_静态代码块 {

     static String name;

     

     // 定义出静态代码块

     static {

      // 1. 可以为静态成员变量进行赋值

      name = "张三";

      System.out.println("静态代码块执行了");

     }

     

     public static void main(String[] args) {

      Demo03_静态代码块 demo = new Demo03_静态代码块();

      System.out.println(Demo03_静态代码块.name);

      

      Demo03_静态代码块 demo1 = new Demo03_静态代码块();

}

}

3.final关键字

1. final : 关键字,表示最终的, 最后的, 不可改变

2. final修饰 : , 方法, 变量(最常用)

  a : 使用final修饰的类, 最终类, 不能当父类, 其他使用一切正常

  b : 使用final修饰方法, 最终方法, 可以被子类继承使用,但是子类不能重写

  c : 使用final修饰变量, 最终变量, 不可改变的变量, final修饰的变量只能手动赋值一次, 值无法修改, 使用final修饰的变量称为常量

1) final修饰基本数据类型, 对应的数值不能修改

2) final修饰引用数据类型, 引用的地址不能修改, 地址中的数据可以修改

3) final修饰成员变量, 需要在变量进入内存之前进行手动赋值

注意 : final修饰变量行业内部命名规则 : 变量名全大写, 多个英文单词之间使用_进行分隔

final修饰类代码

package com.ujiuye.finaldemo;

// 使用final修饰的最终类, 不能有子类

public final class FinalClass {

     int i = 10;

     static int j = 99;

     public void fun() {

      System.out.println("fun-----");

     }

}

package com.ujiuye.finaldemo;

//The type FinalClassZi cannot subclass the final class FinalClass

// 使用final修饰的类FinalClass , 不能有子类

/*public class FinalClassZi extends FinalClass{

}*/

package com.ujiuye.finaldemo;

public class TestFinal {

public static void main(String[] args) {

// 1. final修饰的类可以正常使用

System.out.println(FinalClass.j);// 99

FinalClass f = new FinalClass();

System.out.println(f.i);// 10

f.fun();// fun-----

}

}

final修饰方法代码

package com.ujiuye.finaldemo;

public class FinalMethod {

int i = 1000;

 public void eat() {

 System.out.println("吃饭");

 }

 public final void sleep() {

 System.out.println("每个人每天睡8小时");

 }

}

package com.ujiuye.finaldemo;

public class FinalMethodZi extends FinalMethod {

    // 继承到了父类中的eatsleep

@Override

public void eat() {

 System.out.println("每天只吃两顿饭");

}

/*

 * final修饰的方法功能, 子类可以继承使用,但是不能重写

 * @Override

 public void sleep() {

 System.out.println("每个人每天睡10小时");

 }*/

}

package com.ujiuye.finaldemo;

public class TestFinal {

public static void main(String[] args) {

// 1. final修饰的类可以正常使用

System.out.println(FinalClass.j);// 99

FinalClass f = new FinalClass();

System.out.println(f.i);// 10

f.fun();// fun-----

// 2. final修饰的方法

FinalMethodZi zi = new FinalMethodZi();

zi.eat();// 每天只吃两顿饭

zi.sleep();// 每个人每天睡8小时

}

}

final修饰变量代码

package com.ujiuye.finaldemo;

public class FinalVariable {

// 静态常量

static final String SCHOOL_NAME = "第一中学";

// 5. fianl修饰成员变量, 需要在创建对象完成之前进行final变量的手动赋值

// The blank final field w may not have been initialized(初始化, 表示赋值)

// final修饰的成员变量w, 在进入到内存可以使用之前, 必须完成一次手动赋值

final int w;

public FinalVariable() {

w = 100;

}

public static void main(String[] args) {

// 1. Math数学类中, 有静态成员常量 PI

// static final double PI

System.out.println(Math.PI);// 3.141592653589793

// 2. 修改校名

// The final field FinalVariable.schoolName cannot be assigned

// final修饰变量只能一次手动, 其值无法修改

// FinalVariable.SCHOOL_NAME = "一中";

// 3. final修饰基本数据类型, 表示基本类型的值不可修改

final int i = 10;

// i = 10;

// 4. final修饰引用数据类型, 表示final修饰的fm所对应内存地址不能修改, 没存地址中的数据可以修改

final FinalMethod fm = new FinalMethod();

// fm = new FinalMethod();

fm.i = 999;

}

}

4. Eclipse进阶

  1. 内容辅助生成: alt + /

辅助完成代码补全:

1) main  alt+/ 补全main方法功能

2) syso   alt+/ 补全标准输出语句

3) 关键字补全 : 给出关键字的开头字母, 帮助补全关键字

4) 帮助代码进行命名

5) 常用语法结构, 可以使用alt + / 自动生成和补全

  1. 常用快捷键使用:

1) 导包 : ctrl + shift + o , 将代码中所有的为进行导包的类型统一进行包的导入

2) 注释 :

   a : 单行注释 : ctrl + / , 取消注释 ctrl + /

   b : 多行注释 : ctrl + shift + /, 取消多行注释 : ctrl + shift +

3) 删除 : ctrl + d 每次删除一行内容, 当前鼠标所在行

4) 重命名 : 项目工程, 类重命名, 使用F2(Fn + F2)

开发中常用的快捷键:

5) ctrl + f : 表示查找或者替换

6) ctrl + o : 查看当前类型的大纲内容, 将类型中的成员变量, 方法罗列出来, 点击对应的变量和方法,做代码快速定位

7) ctrl + 代码(变量, 方法,) : 跟进到代码的来源,查看源代码

  1. 代码生成:

   alt + shift + s

5. package

  1. : 就是进行不同的类型文件的分类管理

  

  1. 包的使用:

1) 不同的包package, 可以定义出相同的类名, 类全名带有包名

   举例 : com.ujiuye.homework.Test2;

         com.ujiuye.finaldemo.Test2;

2) 包的命名规则 : 全球唯一, 公司域名倒序写作

   举例 : com.ujiuye.包名(包名表示包的作用)

  1. 导包: 将使用类型所在具体路径使用import关键字进行导入, 需要通过导包, 定位使用的类型所在的具体路径位置, 才能将类型加载进入内存中, 才能使用

1) 同一个package包下的类,可以直接使用,不需要导包

2) 不同package包下的类的使用,需要通过import关键字进行导包

3) java.lang包下的所有类型, 可以直接使用, 不需要导包

4) 在导包时候 import java.util.*; // util下的所有类都可以进行导入, 使用*替代

   但是不建议导入*使用, 使用哪个类型, 导入具体的包, 不要导入*

原文地址:https://www.cnblogs.com/masterhxh/p/13628671.html