【java】学习笔记

b站:韩顺平Java

------------------------------------------------------------------------------------------

第一章 java简介

快速入门

// Hello类
public class Hello {
	// main方法
	public static void main(String[] args) {
		System.out.println("hello world!");
	}
}

在控制台输入以下命令,对.java文件(源文件)进行编译操作,生成Hello.class文件

javac Hello.java

在控制台输入以下命令,运行.class文件(字节码文件)(将.class文件装载到JVM机执行)

java Hello

ps:

1. 文件中有中文时,如何处理?

(1)在Sublime界面按Ctrl + Shift + P打开搜索框,然后输入Install Package,再输入ConvertToUTF8,回车
(2)左上角 文件 -> 设置文件编码 -> GBK
(3)保存,即可重新运行

2. 一个源文件中最多只能有一个public类。

3. 如果源文件包含一个public类,则文件名必须按该类名命名。

4. .java文件中的每一个类,编译后,都对应一个.class文件

转义字符

// 演示转义字符的使用
public class ChangeChar {
	// main方法
	public static void main(String[] args) {
		// \t: 一个制表位,实现对齐
		System.out.println("北京\t天津\t上海");
		// \n: 换行符
		System.out.println("a\nb\nc");
		// \r: 一个回车(将光标移至这行的最前面,所以f会替换掉d)
		System.out.println("de\rf");
		// \\: 一个\
		System.out.println("D:\\javacode");
		System.out.println("D:\\\\javacode");
		// \": 一个"
		System.out.println("\"good\"");
		// \': 一个'
		System.out.println("\'good\'");
	}
}

运行结果:

注释

    单行注释://
    多行注释:/* */
    文档注释:

/**
*@author xxx
*@version 1.0
*/

随后使用命令行

javadoc -d 生成的文件存放的文件夹 -标签(如author) -标签 源文件

Java代码规范

类、方法的注释,要以javadoc的方式(文档注释)来写。
非Javadoc的注释(单行注释、多行注释),往往是给代码的维护者看的,着重告诉读者为什么这样写,如何修改,注重什么问题。

使用tab操作,实现整体往右缩进。
shift+tab整体往左缩进。

源文件使用utf-8编码。

行宽度不超过80。

Dos系统

原理:接受命令->解析命令->执行命令。

0026结束

0190开始

第七章 面向对象编程

一、类和对象

1、定义及区别

        (1)类是抽象的,代表一类事物,比如人类,猫类..,它是数据类型;

        (2)对象是具体的,实际的,代表一个具体事物,它是实例;

        (3)类是对象的模板,对象是类的一个实例。

2、对象内存布局

3、属性(成员变量)

(1)基本介绍

        ① 从概念或者叫法上看:成员变量 = 属性 = field(字段)

        ② 属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(对象、数组等),定义语法同变量;

        ③  属性如果不赋值,有默认值(0、null、false等)。

(2)访问属性

        对象名.属性名: cat1.age

4、对象

(1)创建对象

        ①  先声明再创建

        Cat cat;

        cat = new Cat();

        ②  直接创建

        Cat cat = new Cat();

(2)对象分配机制

(3)Java创建对象的流程简单分析 

①  先在方法区中加载Person类信息(属性和方法信息,只会加载一次,之后用该类创建对象就不用加载了);

②  在堆中分配空间,进行默认初始化;

③  把地址赋给p(p就指向对象);

④  进行指定初始化,比如 p.name = "jack" p.age  = 10。

5、成员方法

(1)方法的定义

访问修饰符 返回数据类型 方法名(形参列表..){ //方法体

        语句;

        return 返回值;

        }

        ①  形参列表

        ②  返回数据类型:表示成员方法输出,void表示没有返回值;

        ③  方法主体:表示为了实现某一功能代码块;

        ④  访问修饰符:作用是控制方法使用的范围

        ⑤  return语句不是必须的。

(2)方法调用机制

分析的代码:

main:

第五步:getSum方法返回后,独立空间被释放

(3)方法的使用细节

        ①  访问修饰符

        作用是控制方法使用的范围,有四种:public,protected,private, 默认。如果不写就是默认访问修饰符。

        ②  返回数据类型

        a.  一个方法最多有一个返回值。如果返回多个结果,就要用到数组;

        b.  返回类型可以为任意类型,包含基本类型或引用类型(数组,对象);

        c.  如果方法要求返回数据,则方法体中最后的执行语句必须为 return 值;而且要求返回值类型必须和return的值类型一致或兼容

        d.  如果方法是void,则方法体中可以没有return语句,或者只写return。

        ③  方法名

        遵循驼峰命名法,最好见名知意,表达出该功能的意思即可。

        ④  形参列表

        a.  一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开,比如:getSum(int n1,int n2)。

        b.  参数类型可以为任意类型,包含基本类型或引用类型,比如:printArr(int[][] map)。

        c.  方法定义时的参数成为形式参数,简称形参;方法调用时的传入参数称为实际参数,简称实参,实参和形参的类型要一致或者兼容、个数、顺序必须一致!

        ⑤  方法体

        里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即方法不能嵌套定义

        ⑥  方法调用细节说明

        a.  同一个类中的方法调回用:直接调用即可。

        b.  跨类的方法调用:需要通过类名调用。

        c.  跨类的方法调用和方法的访问修饰符相关。

(4)方法的传参机制

1. 基本数据类型的传参机制:

a方法调用b方法,给b方法传递基本数据类型,不会影响a方法中数据的值,因为基本数据类型不是引用类型,传递的是值。

2. 引用数据类型的传参机制:

a方法调用b方法,给b方法传递引用数据类型,传递的也是值,但值是地址,所以会影响a方法中数据的值。

3. 对象的传参机制:传的是地址

6、多态

(1)编译时多态性(静态绑定):重载

(2)运行时多态性(动态绑定):继承

public class SuperClass {
    public void method(SuperClass obj1, SuperClass obj2) {
        System.out.println("SuperClass.method(SuperClass, SuperClass)");
    }
}
// SubClass.java
class SubClass extends SuperClass {
    public void method(SuperClass superObj, SubClass subObj) {
        System.out.println("SubClass.method(SuperClass, SubClass)");
    }
    public void method(SubClass subObj, SuperClass superObj) {
        System.out.println("SubClass.method(SubClass, SuperClass)");
    }
    public void method(SubClass subObj1, SubClass subObj2) {
        System.out.println("SubClass.method(SubClass, SubClass)");
    }
}
public class OverloadDemo {
    public static void main(String[] args) {
        SuperClass superObj = new SuperClass();
        SubClass subObj = new SubClass();
        SuperClass superReferToSub = subObj;

        superObj.method(superObj, superObj);
        superObj.method(subObj, subObj);
        superObj.method(superReferToSub, superReferToSub);
        System.out.println("--------------------------------");
        subObj.method(superObj, superObj);
        subObj.method(subObj, subObj);
        subObj.method(superReferToSub, superReferToSub);
        System.out.println("--------------------------------");
        superReferToSub.method(superObj, superObj);
        superReferToSub.method(subObj, subObj);
        superReferToSub.method(superReferToSub, superReferToSub);
    }
}

#### 第二部分:`subObj.method(...)` 调用
- **`subObj.method(superReferToSub, superReferToSub);`**
  - `superReferToSub` 是 `SuperClass` 类型的引用,但在 `SubClass` 的上下文中,它被视为 `SuperClass` 类型. 因此,调用 `SuperClass` 中的 `method(SuperClass, SuperClass)` 方法

#### 第三部分:`superReferToSub.method(...)` 调用

- `superReferToSub` 是 `SuperClass` 类型的引用,指向 `SubClass` 类型的对象.

- **`superReferToSub.method(superObj, superObj);`**
  - 参数类型都是 `SuperClass`,因此调用 `SuperClass` 中的 `method(SuperClass, SuperClass)` 方法.

- **`superReferToSub.method(subObj, subObj);`**
  - 尽管 `subObj` 是 `SubClass` 类型的对象,但在 `SuperClass` 的上下文中,它被视为 `SuperClass` 类型. 因此,调用 `SuperClass` 中的 `method(SuperClass, SuperClass)` 方法.

- **`superReferToSub.method(superReferToSub, superReferToSub);`**
  - `superReferToSub` 是 `SuperClass` 类型的引用,因此调用 `SuperClass` 中的 `method(SuperClass, SuperClass)` 方法.

### 总结
- **静态类型的影响**:在 `SuperClass` 的上下文中,`SubClass` 类型的对象被视为 `SuperClass` 类型,因此会调用 `SuperClass` 中的方法,除非有明确的重载匹配.

7、继承

class Grandpa{
    protected Grandpa(){
        System.out.println("default Grandpa");
    }
    public Grandpa(String name){
        System.out.println(name);
    }
}

class Father extends Grandpa{
    protected Father(){
        System.out.println("default Father");
    }
    public Father(String grandpaName,String fatherName){
        super(grandpaName);
        System.out.println(fatherName);
    }
}

public class Son extends Father{
    public Son(){
        System.out.println("default Son");
    }
    public Son(String grandpaName,String fatherName,String sonName) {
        super(grandpaName,fatherName);
        System.out.println(sonName);
    }
    public static void main(String args[]){
        Son s1 = new Son("My Grandpa", "My Father", "My Son");  // 1
        System.out.println("---------------------");
        Son s2 = new Son();  // 2
    }
}

子类初始化,会先调用父类的初始化函数。

-------------------------------------------------------------------------------

class Base{
    String var="BaseVar";
    static String staticVar="StaticBaseVar";
    void method(){
        System.out.println("Base method");
    }
    static void staticMethod(){
        System.out.println("Static Base method");
    }
}
public class Sub extends Base{
    String var="SubVar";  // 实例变量
    static String staticVar="StaticSubVar";  // 静态变量
    void method(){  // 覆盖父类的method()方法
        System.out.println("Sub method");
    }
    static void staticMethod(){  // 隐藏父类的staticMethod()方法
        System.out.println("Static Sub method");
    }
    String subVar="Var only belonging to Sub";
    void subMethod(){
        System.out.println("Method only belonging to Sub");
    }
    public static void main(String args[]){
        Base who = new Sub();  // who被声明为Base类型,引用Sub实例
        System.out.println("who.var="+who.var);  // who.var=BaseVar
        System.out.println("who.staticVar="+who.staticVar);  // who.staticVar=StaticBaseVar
        who.method();  // Sub method
        who.staticMethod();  // Static Base method
    }
}

- `Base who = new Sub();` 创建了一个 `Sub` 类的实例,并将其赋值给 `Base` 类型的引用 `who`.

- `System.out.println("who.var="+who.var);` 输出 `who.var=BaseVar`:
  - 这是因为实例变量的访问是基于引用的静态类型(即声明类型),而不是对象的实际类型。因此,`who.var` 访问的是 `Base` 类中的 `var`,而不是 `Sub` 类中的 `var`.

- `System.out.println("who.staticVar="+who.staticVar);` 输出 `who.staticVar=StaticBaseVar`:
  - 静态变量的访问也是基于引用的静态类型,而不是对象的实际类型。因此,`who.staticVar` 访问的是 `Base` 类中的 `staticVar`,而不是 `Sub` 类中的 `staticVar`.

- `who.method();` 输出 `Sub method`:
  - 这是因为实例方法的调用是基于对象的实际类型(多态性)。`who` 实际上指向的是 `Sub` 类的实例,因此调用的是 `Sub` 类中覆盖的 `method()` 方法.

- `who.staticMethod();` 输出 `Static Base method`:
  - 静态方法的调用是基于引用的静态类型,而不是对象的实际类型。因此,`who.staticMethod()` 调用的是 `Base` 类中的 `staticMethod()` 方法,而不是 `Sub` 类中的 `staticMethod()` 方法.

### 总结

- **实例变量和静态变量的访问**:都是基于引用的静态类型(即声明类型),而不是对象的实际类型.
- **实例方法的调用**:基于对象的实际类型,表现出多态性.
- **静态方法的调用**:基于引用的静态类型,不表现出多态性.

-----------------------------------------------------------------------------------------------------

class Base {
    int i;
    Base() {
        this.add(1);
    }
    void add(int v) {
        i += v;
    }
    void print() {
        System.out.println(i);
    }
}

class Extension extends Base {
    Extension(){
        add(2);
    }
    void add(int v) {
        i += v*2;
    }
}

public class PolyTester {
    public static void main(String args[]) {
        bogo(new Extension());
        // 以上代码创建的是Extension的实例,所以在运行时,所有调用add()方法的过程,
        // 将始终和Extension类的add()方法动态绑定
        // 1. 先调用父类构造:i = 0 + 1 * 2 = 2
        // 2. 再调用子类构造:i = 2 + 2 * 2 = 6
        // 3. 再调用bogo():i = 6 + 16 = 22
    }
    static void bogo(Base b) {
        b.add(8);
        b.print();
    }
}

0214 00:00

posted @ 2023-12-20 19:50  轻闲一号机  阅读(6)  评论(0)    收藏  举报  来源