华南师范大学计算机学院《Java语言程序设计》笔记

《Java语言程序设计》期末复习提纲 v2.0

PPT:Java-1 计算机与 Java 引论

  1. Java语言的特点(PPT)

简单、面向对象、分布式、半编译半解释(Java源程序经编译器编译后产生字节码,Java解释器解释执行字节码)、平台无关性、安全性、多线程、健壮

Java 是面向对象的。面向对象的编程语言支持三个概念:

(1)封装(encapsulation)

(2)多态性(polymorphism)

(3)继承(inheritance)

  1. JDK环境配置(PPT):

Java_home= C:\jdk1.8

  path=%path%;C:\jdk1.8\bin【%path%表示原有路径,在原有路径的基础上加】

  classpath= .;C:\jdk1.8\lib【.表示当前目录;另一个一般是jre/lib才对,这里当成自定义的一个文件夹就行,注意使用;分隔】

理解这两种环境变量在编译和运行Java程序中的作用。

JAVA_HOME: JDK安装路径,通过这个变量找到必要javac等必要工具,

Path:用于配置程序的路径,可以在命令行中全局访问Java和其他命令行工具,找到java/javac命令的位置

Classpath: 类路径,指向所需类文件的位置,它告诉Java应用程序/java类加载器要在哪里查找用户定义的类以及第三方库

4. Java程序的基本开发步骤, 主要由什么JDK工具完成,能举例说明。(java.exe, javac.exe等)

编辑:IDE

编译: Java编译器javac,命令:javac +.java文件(.java源文件转换成.class字节码文件)

运行:Java应用程序启动器java,命令:java +.java文件

调试:jdb

查看文档:javadoc +.java文件

打包:jar

编译并运行Java程序的基本过程(课本,图1.3):

5.Java源程序结构特点、文件名命名要求

•Java大小写敏感

如果源文件中有多个类,那么只能有一个类是public

•如果有一个类是public类,那么源文件的名字必须与这个类的名字完全相同;若没有public类,那么文件名只需要和某个类的名字相同即可

PPT:Java-2 结构化程序设计

(第2章 基本计算、第3章 流控制—分支、第4章 流控制—循环)

(一)标识符、关键字和数据类型

  1. Java词法(见PPT):UNICODE字符集、空格与分号、注释、标识符、关键字等;

/** JDK的javadoc工具用这种注释信息能自动从程序中抽出类的公共接口形成文档。

    …

*/

2. Java标识符:命名规则、书写约定(PPT)

标识符用作给变量、方法和类命名。

  1. 字母、“_”和“$”开头,后面可跟字母、“_”和“$”或数字
  2. 大小写敏感。
  3. 除去关键字、false、true和null。
  4. 避免与java类库的类名重名
  5. 书写约定:类名、接口名:大驼峰///方法名、对象:小驼峰///常量:全大写///package:全小写

简单判断:

是:$myvariable、_myvariable、猫

不是:9pins、My Variable、a+c

  1. Java字符集采用的是Unicode字符集,它的特点是:每个字符占2个字节(16位),取值范围是0~65535216次方)

转义字符:以反斜杠( \ )开头,将其后的字符转变为另外的含义

代码运行:int x = 0, y = 1, z = 2;
String sString = "x, y, z ";

    System.out.println(sString + x + y + z);

  • System.out.println(x + sString);
    • //输出结果:x, y, z 012
  • 若将第三行改为:System.out.println(sString + (x + y + z));
    • //结果如何?先执行x+y+z=3,输出结果是x, y, z 3

4.Java的关键字,新增加的关键字有instanceof transient synchronized volatile throw throws等

关键词列表:

5. 基本数据类型的定义与使用(PPT或课本)

6. java的数据类型有基本数据类型和引用数据类型两种。引用类型有数组、类、接口、枚举

7.基本数据类型有8种。整数类型范围与占用位数(PPT)。

(二)运算符、表达式和语句

1.Java常用运算符、理解优先级与结合性(PPT),表达式

算术运算符(+,-,*,/,%,++,--):理解/,%,++,--的含义

关系运算符(>,<,>=,<=,= =,!=)

布尔逻辑运算符(!,&&,||, |, &):理解短路运算,注意逻辑与&、逻辑或|,条件与&&、条件或||的区分【采用短路原则】

了解(PPT):

位运算符(>>,<<,>>>,&,|,^,~)

赋值运算符(=,及其扩展赋值运算符如+=)

条件运算符( xx?xx:xx)

其它 (包括分量运算符.,下标运算符[],实例运算符instanceof(判断一个对象是否是某一个类或者其子类的实例)内存分配运算符new,强制类型转换运算符 (类型),方法调用运算符 () 等)

(了解能不能不考啊,左移相当于*2)

 

一个小point,>不能用于比较Strings、booleans、arrays,因为比较的内存地址,但是可以用compareTo方法比较,万能的类!

若想对比两个对象/包装类的实际内容是否相同,使用方法equals(),不能用==

2基本数据类型转换(PPT)

一种类型的值赋给另外类型的一个变量时,将涉及数据类型的转换数据类型的转换有自动转换和强制转换两种形式。

(1)自动类型转换

如果下列两个条件都能满足,那么将一种类型的数据赋给另外一种类型变量时,将执行自动类型转换。这两个条件分别是:

这两种类型是兼容的;

目标数据类型的取值范围比来源数据类型的取值范围要大。

byte(8)<short(16),char(16)-> int(32)->long(64)->float(32)-> double(64)

(2)强制类型转换

当两种类型彼此不兼容,或者目标类型的取值范围小于源类型,自动转换无法进行,这时就需要进行强制类型转换。

代码:byte b;

int i = 258;

b = (byte) i;

运行过程:258的二进制表示为:1 0000 0010,转成byte只取后8位,就是0000 0010 = 2,所以b最后的结果是2

表达式中类型的自动提升(参考PPT的例子):

通用格式:(target-type) value

Java语言规定了若干适用于表达式的类型提升规则(“向高看齐”):

1/ 所有的byte型和short型的值被提升到 int

2/ 如果一个操作数是long,整个表达式将被提升到long

3/ 如果一个操作数是float,整个表达式将被提升到float

4/ 如果有一个操作数是double,计算结果就是double

3. 语句格式与执行逻辑(如Switch、if、while等)

(1)分支语句:if-else, switch-case - else和最近的if匹配,除非有大括号

switch后面括号中表达式的值必须是符合byte,char,short,int类型的常量表达式,而不能用浮点、long和字符串。JDK7开始,允许switch语句使用String类型的控制表达式

(2)循环语句:for, while, do-while

(3)例外处理语句:try-catch-finally, throw

(4)其他: break, return

For each语句:
enum Season{
    春季, 夏季, 秋季, 冬季
}

public class EnumFor{
    public static void main(String args[ ]){
        for ( Season c : Season.values( ))
            System.out.print(c + ", ");
        System.out.println( );
    }
}

Lable好像还不是很懂、、、【todo

  1. 了解断言(assert)语句的基本语法。

语法:assert expression;

expression是一个返回布尔值的表达式。如果expression计算结果为false,则抛出AssertionError

PPT:Java-3 面向对象程序设计(类、对象和接口)(重点全面理解)

(第5章 定义类和方法、第6章 对象和方法进阶、第8章 继承、多态和接口)

  1. 了解面向对象的类的三个基本特性:封装性、继承性和多态性

2. 掌握类、成员变量和方法的定义(课本和PPT)

类的定义

[类修饰词] class 类名 [extends 父类名] [implements 接口名称列表]

{

    类体

}

2.1 类修饰符:包括public abstract final等,理解“无修饰词”的含义。

  1. 公共类修饰符public Java 语言中类的可访问控制符只有一个:public 即公共的。每个 Java程序的主类都必须是public类作为公共工具。供其它类和程序使用的应定义为public
  2. 抽象类修饰符 abstract :凡是用 abstract 修饰符修饰的类,被称为抽象类。所谓抽象类是指这种类没有具体对象的一种概念类。
  3. 最终类修饰符 final 当一个类不可能有子类时可用修饰符 final 把它说明为最终类。被定义为 final 的类通常是一些有固定作用、用来完成某种标准功能的类。
  4. 类缺省访问控制符:如果一个类没有访问控制符,说明它具有缺省的访问控制符特性。此时,这个类只能被同一个包中的类访问或引用。这一访问特性又称为包访问性

2.2 构造方法的概念与定义方法;

构造函数重载overloaded如果有this()语句则必须是其中的第一句,必须有不同的参数

       变量和方法称为类的成员(成员变量和成员方法),而构造方法不是类的成员

       每个类中至少有一个构造方法

       定义类时如未定义构造方法,运行时系统会为该类自动定义缺省的构造方法

【默认值: 基本数值类型: 0; boolean: false; 引用数据类型: null

2.3成员变量的声明

注意其修饰词的含义:访问控制、staticfinal (修饰词包含:public protected private static final transient volatile)

  1. public:被该修饰符修饰的成员变量可以被任何类使用
  2. protected:被该修饰符修饰的成员变量能被该类自身、本包中的类、和子类(是子类而非父类)所使用,即用protected修饰的属性在其他包中的子类中可以通过子类对象进行访问,不能通过本类对象进行访问
class Person {

    protected String name;


    public Person(String name) {

        this.name = name;

    }


    public String getName() {

        return name;

    }

   

public void printName() {

// 解释:不能通过本类对象进行访问

// 不能直接sout(name),必须通过getter方法才能获取到

        System.out.println(getName()); // 使用访问器方法获取 name

    }

}
  1. private:被该类使用【不能被子类和外类使用】
  2. 缺省:只能被该类、本包中的类所使用
  3. static类变量,可以被类直接使用
  4. final:常量,值不能被改变
  5. transient java中的关键字,被修饰的变量不能被序列化
  6. volatile关键字:使系统中所有线程对该关键字修饰的变量共享可见

2.4成员方法的声明

1)注意其修饰符的含义:访问控制、staticabstractfinal

Static:属于类而不是类的实例,可以直接通过类名调用,只能访问类的其他静态成员

Abstract:在抽象类中声明、子类必须实现这些抽象方法,不能被实例化(创建对象)

Final:不能被子类重写

2)理解传值调用与引用调用(PPT中的例子)

①本质都是值传递,只不过后者是传了个地址而已

②当传值调用时,改变的是形参的值,并没有改变实参的值。实参的值是可以传给形参的,但是形参的值不能传给实参。

void celebrateBirthday(int age) {

    age = age + 1; // Celebrate and add one year

}

int myAge = 25;

celebrateBirthday(myAge); // 传值调用

System.out.println(myAge); // 输出25

③当引用调用时,如果参数是对象,无论对对象做了何种操作,都不会改变改变实参对象的引用(可参考String,但是,如果改变了对象的内容,就会改变实参对象的内容,因为形参变量和实参变量共享一块堆区。

class Age {

    int value;

}

void celebrateBirthday(Age age) {

    age.value = age.value + 1;

}

Age myAge = new Age();

myAge.value = 25;

celebrateBirthday(myAge); // 引用调用

System.out.println(myAge.value); // 输出 26

3.对象的声明(声明时并不创建对象)、创建(实例化)、初始化与使用(new操作符,Java垃圾收集机制:PPT中System.gc()和finialize()方法)

声明:Rectangle rect;

创建:rect = new Rectangle();

创建同时初始化:Rectangle rect2 = new Rectangle (25);

4static关键字(类成员与实例成员)

       1)理解类变量与实例变量的区别与使用方法

       实例变量对对象而言是独立的;类变量对对象而言是公用的。

       2)理解类方法与实例方法的区别与使用方法

       实例方法只能由对象调用,并且可以操作类变量与实例变量;而类方法既可以由类调用又可以由对象调用,并且类方法只能对类变量进行操作

       static 修饰的类的成员变量或成员方法,可以通过类名直接调用成员变量或方法。

Main方法必须要用static修饰

Static方法只执行一次,且在最开始执行

5.理解super的基本用法

访问父类的成员变量:System.out.println(super.num); // 打印父类的num

调用父类的方法:

    void display() {

        super.display(); // 调用父类的display()

        System.out.println("Child display()");

    }

调用父类的构造器

class Child extends Parent {

    Child() {

        super(); // 调用父类的构造器,不写时默认调用

        System.out.println("Child Constructor");

    }

}

6this关键字的含义与使用方法

       this 是一个类的当前实例(对象)的引用。只能在实例方法定义内使用它。在类方法或用static 说明的方法中不能用this 。

引用当前对象的属性【this.age】、引用当前对象的方法【this.show()】、传递当前对象为参数【passObject(this);】、返回当前类的实例【return this】、调用当前类的构造器【this(0, "Anonymous");

7.包装器类(Wrapper

       (1)Java为每种基本类型都提供了包装器类包装器类没有缺省构造器

       (2)从int的基本类型—》其对应的包装器类(例如Integer)的转换:装箱。

(3)从包装器类—》其关联的基本类型的转换称为拆箱。

通过PPT或教材的例子,掌握包装器类的基本使用方法。

装箱过程通过调用包装器的valueOf()实现的,而拆箱过程调用包装器的 xxxValue()实现的。

好处: 包装类提供了多种方法来操作基本类型

       包装类的对象可以为null,代表没有值,而基本类型总是有默认值(如int0)。这个特性在表达缺失或无效值时非常有用。

Java的集合类(如ArrayList, HashMap等)只能存储对象,不能直接存储基本数据类型。包装类使得基本类型可以被存储在这些集合中。

toString方法的联系

  1. 当你想将一个基本类型的值转换为字符串时,你可能会先将它装箱成包装类对象,然后利用包装类的toString()方法
  2. 一般是先检查是否为null再进行拆箱(否则报错NullPointException),检查是否为null的时候就先用tostring转一下

Integer myInteger = null;

String text = "The value is: " + myInteger; 

// 不会抛出异常,text将是"The value is: null"

常见错误:缺少返回语句(if)、变量未初始化

8.理解包(package)(详见PPT)

       (1)包的作用:包是一组相关的类或接口的集合, 它提供了访问保护和名字空间管理。Java编译器使用文件系统目录来保存包。

       (2)包的创建与命名规则

格式:package pkg1[.pkg2[.pkg3]]

package语句必须放在原文件的开始处,一般全部采用小写ASCII字母

       (3)包的使用

import pkg1[.pkg2].类名   通配符*

包中的所有类中只有public类能被包外部的类访问。

       (4)包中的源文件与类文件的管理(注意目录层次与包定义的对应关系,阅读PPT的例子)

1. com.example.myapp,则对应的目录结构应该是com/example/myapp

2. 源文件应该直接位于其声明的包对应的目录中

类声明为package com.example.myapp;,该类的源文件应该位于com/example/myapp目录下。

3. 一般会将.class文件放在一个单独的目录(如bin, outbuild)中,与源代码(src)目录分开

9.理解访问控制级别

(1)成员变量和方法有4种访问级别:

              public, protected, 默认(default,即没有访问控制修饰符,代表包范围可访问,也就是说子类和类如果不在一个包中也不可以访问), private ;

      (2)类有两种访问级别:public 或default默认。

       3)修饰符的作用范围:

Modifier      Same class     Same Package         Subclass         Universe

public          Yes          Yes                     Yes                Yes

protected      Yes          Yes                      Yes

default       Yes         Yes

private       Yes

(4)通过例子去理解(PPT【去看2.32.4啦】

没有包定义就在默认包

10Java的继承机制:单继承机制,不支持多重继承,但可以通过接口来实现多重继承(即通过继承父类,在此基础上再实现某个接口)

       (1)子类继承父类的形式:extends。Java中,所有的类都是通过直接或间接地继承java.lang.Object得到的。一个类如果没有声明继承某个类,则默认继承Object类。在对实体类的集合元素操作时,实体类通常重写Object类的equals()hashCode()方法实现对象的比较(阅读教材:8.2.8 更好的equals方法;阅读第8章PPT的HashSet类),为了便于输出定制化的信息,子类也通常会重写Object类的toString()方法

       (2)子类的继承性

       子类能够继承什么?

如果子类与父类在同一个包内:

子类能够继承其父类中所有非private(即public、protected和default)的成员变量和成员方法

如果子类与父类不在同一个包内:

子类能够继承其父类中所有public和protected的成员变量和成员方法,但不能够继承其父类中的default和private

子类不能继承父类隐藏的成员变量和重写的父类方法

子类不能继承父类中构造方法。因为构造方法不是类的成员

       3)成员变量的隐藏与方法的重写

       1、成员变量的隐藏与方法重写的规则(详见PPT)

父类中同名变量不能被继承——即子类同名变量隐藏父类中的同名变量。

子类中定义的同父类完全相同的方法将隐藏父类中的方法——运行时多态性。

子类调用父类方法的方法(包括同名方法)——super.xxxYYY();

变量的隐藏:子类中声明了和父类同名的变量,父类的成员变量被隐藏。

方法的重写:子类中定义了与父类相同的方法, 则父类的方法被重写。

       4)方法的重载(overload也称为静态多态性,静态多态性在编译时可以被系统识别

       在同一个类中名字相同但参数个数或类型不同的方法。返回值可以不同。

       构造方法也可以重载。

       5)运行时多态(overwrite,即重写)

       1、对子类的一个实例,如果子类重写了父类方法则调用子类的方法;如果子类继承了父类的方法则调用父类的方法。

       重写父类的方法时,不可以降低方法的访问权限;重写的方法和父类中被重写的方法要具有相同的名字,相同的参数表和相同的返回类型。

  1. 名字、参数表、返回类型必须相同
  2. 不能重写final方法
  3. 必须实现abstract方法
  4. 不可以降低方法访问权限

       2、对象的上转型对象

       对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。理解上转型对象的特点。 (PPT)

A a;

a=new B();  a就是b的上转型对象,就是父类但是子类原有的方法和变量

特点:

  • 上转型对象不能操作子类新增的成员变量和成员方法(失掉了部分属性或功能)
  • 上转型对象可以操作子类继承或重写的成员变量和成员方法

③如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时是调用了这个重写的方法

3、理解运行时多态的作用(课本或PPT的例子)

主要通过方法的重写(Override)实现

  1. 接口统一,实现多样
  2. 提高代码的可维护性
  3. 促进代码复用
  4. 实现解耦
  5. 支持动态方法调用

       (6)final数据、方法和类

       1、final数据可以是编译时的常量,也可以是运行时才初始化的常量

       2、final方法不能被重写

       3、final类不能被继承

       7abstract类、abstract方法

1、抽象类不能实例化——创建对象。

2、抽象方法只允许声明,不允许实现。

3、抽象类中不一定要包含abstract方法,但是一旦某个类中包含了abstract方法,则这个类必须声明为abstract类。

       8)通过例子理解类之间的is-a关系(“是一个”关系)和has-a关系(“有一个”关系)的含义。

只有在一个类和派生类存在“是一个”关系时才应该使用继承。Student is a Person【特殊和一般,类和类的继承】(阅读新教材:8.1.1 派生类)

另一种方式称为“有一个”关系。通过在Student类中添加Date类型的实例变量,就可以在Student类中添加录取日期。Student has a Date。【组合,类和类的成员变量】阅读新教材:编程窍门:“是一个”和“有一个”关系)

11.理解接口

       1)接口的概念:接口就是方法定义(没有方法的实现)和常量值的集合。

    public interface Sleeper {

         public void wakeUp();

           public void beep();

           public long ONE_SECOND = 1000;

           public long ONE_MINUTE = 60000;

    }

       2)接口的作用、接口与多重继承的区别

       1、一个类仅仅继承接口中的常量、不能继承接口中的方法。

2、接口继承独立于类的继承。执行相同接口的类,不一定在类继承上相关。

3、接口也使用extends继承接口,但与类继承不同的是,接口继承时允许继承多个接口

多重继承复杂且可能导致多种问题,如“菱形问题”(当两个父类具有相同的方法或属性时,子类不知道应该继承哪个)。因此,Java不支持直接的多重继承。

       (3)接口的声明与定义(特征与使用规则,见PPT):

       1、在接口中定义的常量具有public, final ,static的属性。

2、实现中不能缩小接口方法的访问类型:接口中的方法被默认是public的,所以类在实现接口方法时,一定要用pulbic来修饰.

接口中成员域都具有public,static和final属性

Static:接口不能被实例化,因此它的字段不应该是实例变量

Final:接口的字段默认是常量,不应该被修改

接口中成员方法都具public和abstract属性

       4)接口的使用

       1、类声明使用接口的关键字:implements

       2、使用接口的类体中可以使用接口中定义的常量

3、必须实现接口中定义的所有方法

如果一个类声明使用一个接口,但没有实现接口中的所有方法,那么这个类必须是abstract

4、在类中实现接口所定义的方法时,方法的声明必须与接口中所定义的完全一致。

       5、接口的回调问题:Java运行时系统动态地确定该使用哪个类中的方法。(PPT中的例子)

// 触发回调的类
class Trigger {
    Callback callback;

    void registerCallback(Callback callback) {
        this.callback = callback;
    }

    void doSomething() {
        // 在适当的时候触发回调
        if(callback != null) {
            callback.call();  // 动态确定调用哪个对象的call方法
        }
    }
}

// 测试回调
public class TestCallback {
    public static void main(String[] args) {
        Trigger trigger = new Trigger();
        A a = new A();
        B b = new B();
// 也就是这里才决定调用的是哪个类动态调用
        trigger.registerCallback(a);  // 注册A的回调
        trigger.doSomething();  // 输出 "A's call method"
        trigger.registerCallback(b);  // 更改回调为B
        trigger.doSomething();  // 输出 "B's call method"
    }
}

12.了解什么是匿名内部类:匿名内部类不具有类名,不能具有抽象和静态属性,不能派生子类。

用途:

事件处理:在图形用户界面(GUI)编程中,匿名内部类常用于事件监听和处理。

即时运行:当需要用到某个类的简单或临时实现时,匿名内部类允许快速地实现接口或类扩展。

减少代码臃肿:有助于减少编写额外类的需求,使代码更加简洁。

// 没有匿名内部类时必须创建接口、实现接口、创建对象、调用对象方法
interface OnClickListener {
    void onClick();
}
// 实现接口的一个具名类
class ClickListener implements OnClickListener {
    public void onClick() {
        System.out.println("Button clicked!");
    }
}
// 使用具名类创建监听器
Button button = new Button();
button.setOnClickListener(new ClickListener());
Button button=new Button();

// 使用匿名内部类直接在这里实现OnClickListener接口
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(){
        System.out.println("Button clicked!");
      }
  });
 

13. PPT小结:再思考动态绑定的问题

(1)绑定:就是类之间存在的关联,体现在类的方法调用上的相互关系。

有静态绑定(编译时绑定/私有方法、静态方法和final方法)和动态绑定(运行时绑定/运行时多态)

(2)运行时多态的两种实现方法:

1、通过上转型对象来实现运行时多态

子类重写了父类的方法,运行时,将子类的对象赋给父类的类型变量(上转型对象),最终上转型对象调用的是子类对象的重写过的方法,实现运行时多态。

这是通过类的继承关系来实现的多态。

  • 上转型指的是将子类的引用赋值给父类类型的变量。
  • 子类可以重写父类的方法,当通过父类类型的变量调用这些方法时,实际执行的是子类中重写的版本,这是继承和重写实现多态的典型方式。
  • 这种方式是通过类的继承层次结构来实现的。

       (通过PPT的例子掌握这种上转型对象的运行时多态的使用方法。PT:p177

class Animal {
    void sound() { System.out.println("Some sound");    }
}

// 子类1
class Dog extends Animal {
    @Override
    void sound() {  System.out.println("Bark");    }
}

// 子类2
class Cat extends Animal {
    @Override
    void sound() {  System.out.println("Meow");    }
}

public class TestPolymorphism {
    public static void main(String[] args) {
        // 上转型:将子类对象赋给父类引用
        Animal myAnimal;
        // 动态绑定 Dog 的 sound 方法
        myAnimal = new Dog();
        myAnimal.sound();  // 输出:Bark
        // 动态绑定 Cat 的 sound 方法
        myAnimal = new Cat();
        myAnimal.sound();  // 输出:Meow
    }
}

2、通过接口类型来实现运行时多态

类实现了某些接口,然后再以接口类型的实例变量的方式,使用接口的方法。

这是不同类(不一定有继承关系)之间,由共同拥有/实现的接口来实现的多态。

  • 类可以实现一个或多个接口,并提供接口中声明的方法的具体实现。
  • 通过接口引用来调用这些方法时,实际执行的是实现类中的方法。
  • 这种方式使得不同的类可以通过共同实现的接口来表现出多态性,即使它们之间没有继承关系。

       (通过PPT的例子掌握这种接口回调的运行时多态的使用方法。PPT:p224

// 接口
interface Shape {
    void draw();
}

// 实现类1
class Circle implements Shape {
    public void draw() {  System.out.println("Drawing Circle");  }
}

// 实现类2
class Rectangle implements Shape {
    public void draw() {  System.out.println("Drawing Rectangle"); }
}

public class TestPolymorphism {
    public static void main(String[] args) {
        // 通过接口引用来调用方法
        Shape shape;
        // 动态绑定 Circle 的 draw 方法
        shape = new Circle();
        shape.draw();  // 输出:Drawing Circle
        // 动态绑定 Rectangle 的 draw 方法
        shape = new Rectangle();
        shape.draw();  // 输出:Drawing Rectangle
    }
}

动态绑定(动态多态),是在运行时才确定最终调用哪个实例的方法,通过这种方式,将问题推延到运行时才解决,而不是设计时解决,使程序具有良好的扩展性,能够灵活适应将来不断变化的情况。

PPT:Java-4 数组与字符串

(第7章 数组,第2章 基本的计算的2.2 String类)

  1. 数组的声明与创建(掌握一维和二维数组的声明与使用)

相同的数据类型元素类型

一维数组变量的声明格式有如下两种:

(1)   数组元素的数据类型      [ ]      变量名; (推荐)

(2)   数组元素的数据类型      变量名      [ ];

int[ ] c = new int[12];

Cat[ ] maomao = new Cat[5];

int[ ][ ] a = new int[3][4];

int[][] a = new int[2][ ]

a[0] = new int[3];

int twoDim [][] = new int [][ 4];  //error

基本数据类型的元素初始化为0值或false

非基本数据类型的元素初始化为null

2.数组元素的构成特点(简单类型数据与引用类型数据)

3.数组的基本术语:索引,索引变量等(图7.2 有关数组的术语)

4.数组的操作:数组初始化与数组元素的赋值

动态初始化:先定义数组分配空间,然后直接对每个元素进行赋值:int[] nums;

nums = new int[2];

nums[0] = 1; nums[1] = 2;

静态初始化:在定义数组的同时进行初始化,不需要指定数组大小:int[ ] n = { 10, 20, 30, 40, 50 };

== 判断内存是否在同一地址,equals()判断数组内容是否相等

5String对象的定义方法与基本操作(长度、相等判断,课本与PPT

       掌握:length(),equals(),parseXXX()subString()[该子串从beginIndex开始, endIndex - 1结束]indexOf()[搜索指定串出现的位置]String对象的+==操作(比较的是内存地址)  

charAt()equalsIgnoreCasestartsWithcompareTo

(1)基本数据类型可通过String类的valueOf()方法转换得到字符串表达形式。【获取的是包装类】,对于对象则可以调用其继承的基本根类Object中的toString()来转成字符串表达形式。

(2)把字符串转换成基本数据类型由包装器(wrapper)类Byte Integer Long Double Float等中定义的parseXXX()【获取的是普通类型】系列方法完成。

s1 = hello;  // 字符串直接量

s2 = new String( "hello" );

s1 == "hello";   // true

s2 == "hello";   // false

6. 理解main()方法中的参数数组与使用(PPT:p21)

PPT:Java-5 异常处理和递归

(第9章 异常处理、第11章 递归)

1.异常的概念与异常的基本分类:

       (1)受检异常(Checked Exception):在编译时能被Java编译器所检测,需要进行异常处理。

•必须在方法声明时通过throws列出

•在编译时就能被检测出

       (2)非受检异常(Unchecked Exception):包括运行时异常和错误,在编译时无法被检测。其中运行时异常只有在程序运行时才能被检测到,错误异常在程序中无法被处理。

•不必在throws列表中

•错误(Errors) 和运行时例外(RuntimeExceptions)

所有的异常类都是Throwable的子类。异常对象由throw语句抛出。

  1. 了解异常(Exception)的层次结构(PPT:p19,6.1)

可检查异常和不可检查异常

可检查异常指在编译时必须处理的异常,都直接或间接继承java.lang,Exception,包括IOExceptionFileNotFoundExpection等等

不可检查异常通常由编程错误引用,继承java.lang.RuntionException,包括NullPointExceptionArrarIndexOfBoundsException等等

  1. 通过例子掌握异常的处理过程:异常的抛出、捕获和处理(try/catch/finally)(PPT中的练习题)

Java的异常处理是通过5个关键词来实现的:trycatchthrowthrowsfinally

一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throw)一个异常,这时候可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。

当程序运行中发生异常时,异常处理机制将按以下步骤处理:

  1. 产生异常对象并中断当前正在执行的代码,抛出异常对象
  2. 自动按程序中的catch的编写顺序查找“最接近的”异常匹配。一旦找到就认为异常已经得到控制,不再进行进一步查找。这个匹配不需要非常精确,子类对象可以与父类的catch相匹配。
  3. 若有匹配则执行相应的处理代码,然后继续执行本try块之外的其他程序。否则这个没有被程序捕获的异常将由缺省处理程序处理,缺省处理程序将显示异常的字符串、异常发生位置等信息,终止整个程序的执行并退出

try{

//可能产生异常的语句序列

}

catch(Exception1 e1){

//针对异常类型Exception1的处理代码

}

catch(Exception2 e2){

//针对异常类型Exception2的处理代码

}

catch(ExceptionN eN){

//针对异常类型ExceptionN的处理代码

}

finally{

//最后总是会被执行的语句,不管是否有异常产生

}

4.掌握递归的实现方法(作业)【todo

5. 重点掌握单体设计模式的实现原理(看PPT的例子)

可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。

PPT:Java-6 JavaFX GUI

(每一章的图形化编程补充读物汇总)

1.了解JavaFX应用程序中绘图区域的坐标系(原点)、stage类、scene类和GraphicsContext类的概念以及它们之间的关系和基本用法。

       Group root = new Group();

       Scene scene = new Scene(root);

       primaryStage.setScene(scene);

       primaryStage.show();

@Override
public void start(Stage primaryStage) throws Exception   {//stage【主要画布】
    Group root = new Group();//【图层】用于组织JavaFX节点的容器。这里用来存放绘制的笑脸图形。
    Scene scene = new Scene(root);//【特定区域】表示JavaFX场景,场景是应用程序用户界面的容器。

    Canvas canvas = new Canvas(400, 300);  //【具体画布】可绘制图形的区域
    GraphicsContext gc = canvas.getGraphicsContext2D(); //图形上下文【画笔】通过它可以进行图形绘制操作。
    gc.strokeOval(100, 50, 200, 200);//空心椭圆,参数分别表示椭圆的位置和尺寸
    gc.fillOval(155, 100, 10, 20);//一个实心椭圆,参数表示椭圆的位置和尺寸。
    
gc.setFill(Color.RED); //右眼设置成红色
gc.fillOval(230, 100, 10, 20);//再次使用fillOval方法绘制笑脸的右眼。
    gc.strokeArc(150, 160, 100, 50, 180, 180, ArcType.ROUND);//绘制一个弧线,笑脸的嘴巴。

    root.getChildren().add(canvas);//将Canvas对象添加到Group容器中,以便在Scene中显示。

    primaryStage.setTitle("HappyFace in JavaFX");//标题
    primaryStage.setScene(scene);//场景
    primaryStage.show();//显示
}

2.通过PPT或新教材中的例子,了解 JavaFX基本组件类的用途:Label类、Button类、TextField类、TextArea类、CheckBox类、RadioButton类。

Label显示文本或标签:Label label = new Label("用户名:");

Button创建可单击的按钮:Button submitButton = new Button("提交");

TextField接收单行文本输入:TextField usernameField = new TextField();

TextArea接收多行文本输入:TextArea commentArea = new TextArea();

CheckBox表示二进制选项的复选框:CheckBox cb = new CheckBox("启用");

RadioButton表示一组互斥选项的单选按钮

3.通过PPT或新教材中的例子,了解 JavaFX以下几种布局的特点:Hbox、Vbox、BorderPane、GridPane、StackPane、FlowPane。

 

4.掌握事件驱动模型的基本原理和实现方法(见PPT)

       (1)基本概念:事件源、事件类与对象、监视器类、事件处理器,理解它们之间的关系。

事件源是能够产生事件的对象,事件是描述事件源发生事件的对象,监视器类是一个类,事件处理器是一个方法或一组方法

       2)掌握常见的事件类型的接口名以及该事件的处理方法:

        按钮事件处理ActionEvent(掌握匿名内部类、独立监听器类、匿名内部类转换成Lambda函数的表达方式):

// 使用匿名内部类
btnSunny.setOnAction(new EventHandler<ActionEvent>(){
public void handle(ActionEvent event){
        lblMessage.setText("It is sunny!");
        }
   });

// 使用独立监听器类
public class SunnyButtonHandler implements EventHandler<ActionEvent> {
    public void handle(ActionEvent event) {
        lblMessage.setText("It is sunny!");
    }
}

// 注册独立监听器类
btnSunny.setOnAction(new SunnyButtonHandler());

// 使用Lambda表达式(匿名内部类的简化形式)
// 就是 对象->返回值
btnSunny.setOnAction(event->lblMessage.setText("It is sunny!"));

MouseEvent(鼠标事件)

KeyEvent(键盘事件):

WindowEvent(窗口事件):

5、了解Lambda函数的基本写法和用法,通过例子掌握Lambda表达式在图形事件处理中的基本用法。(PPT的例子)

6、了解JOptionPane类中的几种常用方法:JOptionPane.showConfirmDialog、JOptionPane.showMessageDialog等。

JOptionPane.showConfirmDialog显示一个确认对话框

int result = JOptionPane.showConfirmDialog(null, "是否保存更改?", "确认对话框", JOptionPane.YES_NO_CANCEL_OPTION);
if(result==JOptionPane.YES_OPTION){
        // 用户选择了“是”按钮
}else if(result==JOptionPane.NO_OPTION){
        // 用户选择了“否”按钮
}else if(result==JOptionPane.CANCEL_OPTION){
        // 用户选择了“取消”按钮
}

JOptionPane.showMessageDialo用于显示一个信息对话框

JOptionPane.showMessageDialog(null, "操作成功!", "信息对话框", JOptionPane.INFORMATION_MESSAGE);// 信息消息,显示信息图标

showInputDialog 用于显示一个输入对话框,允许用户输入文本或选择一个选项。

String input = JOptionPane.showInputDialog(null, "请输入您的姓名:", "输入对话框", JOptionPane.PLAIN_MESSAGE);

7、掌握本章的实验(简单计算器)【todo】

PPT:Java-7 流、文件IO和网络

(第10章 流、文件I/O和网络)

1、输入流与输出流的基本概念:

Java的数据流根据操作的数据流分为字节流和字符流

1)字节流(Byte Streams) :流中的数据以8位字节为单位进行读写,以InputStream和OutputStream为基础类。FileInputStreamFileOutputStream

       2)字符流(Character Streams) :流中的数据以16位字符为单位进行读写,以Reader和Writer为基础类。FileReaderFileWriter

一般地,字节流类主要用于读写诸如图象或声音等的二进制数据,而字符流适用于处理文本数据

2. 理解标准输入/输出/错误流(System.in/System.out/System.err) 的用法

 

4.理解用于文件和目录管理的 java.io.File 类。

myFile = new File("myfile.txt");

String getName()    String getPath()    String getAbsolutePath()

String getParent()    boolean renameTo( File newName)

boolean exists()     boolean canWrite()

boolean canRead()   boolean isFile()    boolean isDirectory()

long length()         boolean mkdir()

FileInputStream 以字节为单位从文件中输入数据

FileOutputStream以字节为单位输出数据到文件中

FileInputStream in=new FileInputStream(fp);

FileOutputStream out=new  FileOutputStream(fp);

FileReader 以字符为单位读取文件数据

FileWriter以字符为单位写数据到文件中

File inputFile = new File("farrago.txt");

File outputFile = new File("outagain.txt");

FileReader in = new FileReader(inputFile);

FileWriter out = new FileWriter(outputFile);

int c;

while ((c = in.read()) != -1)

   out.write(c);

in.close();

out.close();

  1. 了解 Scanner类的作用
/ 从标准输入读取数据
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt();

// 从文件中读取数据
File file = new File("example.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
    String line = scanner.nextLine();
    // 处理每一行数据
}
scanner.close(); // 关闭文件流
        
// 解析不同类型的数据
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数: ");
int number = scanner.nextInt();
System.out.print("请输入一个浮点数: ");
double decimal = scanner.nextDouble();
System.out.print("请输入一个字符串: ");
String text = scanner.next();

5重点掌握类对象的序列化和反序列化过程。掌握对象序列化和反序列化的基本实现原理(PPT和课本的描述与例子)

       序列化分为两部分:序列化和反序列化。

序列化是将对象状态数据分解成字节流(二进制),以便存储在文件中或在网络上传输。

反序列化是打开、输入字节流并在内存中重构对象。

一个类如果实现了Serializable接口,则这个类创建的对象就是可序列化的对象。声明为transientstatic的变量不能被序列化。

Serializable接口中没有方法,所以实现该接口的类不需要实现额外的方法。

一个可序列化的类的子类创建的对象也是可序列化的。

序列化步骤:

1. 只有实现Serializable接口的类才能被序列化:implements Serializable

2. 构造对象的输入输出流(将对象保存到文件中,或者通过网络传送到其他地方)

FileOutputStream fileOut = new FileOutputStream("object.ser");

ObjectOutputStream out = new ObjectOutputStream(fileOut);

3.写入对象:使用ObjectOutputStreamwriteObject将对象写入输出流

MyObject obj = new MyObject();

out.writeObject(obj);

4.关闭输出流

       MyObject obj = new MyObject();

out.writeObject(obj);

反序列化步骤

1.创建ObjectInputStream

FileInputStream fileIn = new FileInputStream("object.ser");

ObjectInputStream in = new ObjectInputStream(fileIn);

2. 读取对象

       MyObject obj = (MyObject) in.readObject();

3.关闭输入流

       in.close();

对象序列化和反序列化的实现原理基于 Java 的序列化机制。Java 使用反射机制检查类的字段,将对象的状态写入字节流,并在反序列化时重新构建对象。这意味着被序列化的类必须具有默认的无参数构造函数,以便在反序列化时创建对象。

序列化然后反序列化查看结果会出现:

实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

private static final long serialVersionUID;

PPT:Java-8 动态数据结构和泛型

(第12章 动态数据结构和泛型)

  1. 掌握泛型的三种定义与使用方法(PPT)【todo

类泛型适用于整个类,方法泛型适用于特定方法,而通配符泛型允许更灵活地处理不同类型的参数。

类泛型:允许你在定义类时使用参数化类型。你可以在类名后面添加尖括号。

public class MyGenericClass<T> {

    private T value;

    public MyGenericClass(T value) {   this.value = value;    }

    public T getValue() {   return value;    }

}

// 使用泛型类

MyGenericClass<String> strObj = new MyGenericClass<>("Hello");

String strValue = strObj.getValue();

方法泛型:允许你在定义方法时使用参数化类型,与类泛型不同,方法泛型的类型参数可以与类泛型的类型参数不同

public class MyGenericMethod {

    public <T> void printArray(T[] arr) {

        for (T item : arr) {   System.out.print(item + " ");       }

        System.out.println();

    }

}

// 使用泛型方法

Integer[] intArr = { 1, 2, 3, 4, 5 };

String[] strArr = { "one", "two", "three" };

MyGenericMethod genericMethod = new MyGenericMethod();

genericMethod.printArray(intArr);  // 输出整数数组

genericMethod.printArray(strArr);  // 输出字符串数组

通配符泛型:允许你在方法参数中使用通配符(?)来表示不确定的类型。这样可以使方法更加灵活,能够接受不同类型的参数。

public void processList(List<?> list) {

    for (Object item : list) {   System.out.print(item + " ");  }

    System.out.println();

}

// 使用通配符泛型方法

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);

List<String> strList = Arrays.asList("one", "two", "three");

processList(intList);  // 处理整数列表

processList(strList);  // 处理字符串列表

  1. 了解枚举的定义与使用(结合PPT和课本的例子进行理解)

不能通过new运算符创建实例对象,可直接通过枚举类型标识符访问枚举变量

通过成员方法values获得该枚举类型的所有枚举变量,如:Season [ ] s2=Season.values();

enum Season {
    春季, 夏季, 秋季, 冬季
} // 枚举Season结束,不能通过new创建实例对象

public class EnumDemo {
    public static void main(String args[]) {
        Season[] sa = Season.values();
        for (Season season : sa) {
            switch (season) {
                case 春季:
                    System.out.println("春天不是读书天");
                    break;
                case 夏季:
                    System.out.println("夏日炎炎正好眠");
                    break;
                case 秋季:
                    System.out.println("秋又凄凉冬有雪");
                    break;
                case 冬季:
                    System.out.println("收拾书箱好过年");
                    break;
            } // switch结构结束
        } // for循环结束
    } // 方法main结束
} // 类EnumDemo结束

  1. 掌握for语句的简化写法(foreach)。某类要支持使用foreach写法,要求该类具有成员方法iterator()或者实现Iterable接口(PPT:p20)。
public class IntegerFor{
    public static void main(String args[ ]){
        int [ ] a = {10, 20, 30, 40, 50};
        int s = 0;
        for ( int c : a)
            s += c; // 这里需要注意c是数组的元素,而不是相应的下标
        System.out.println("数组a的元素之和等于" + s);

        s = 0;
        int [ ] ca = a;
        for ( int i=0; i< ca.length; i++ ){
            int c = ca[i];
            s += c;
        }
        System.out.println("数组a的元素之和等于" + s);
    }
} 

4、了解Java集合框架中常见类和接口的特点(ArrayList、HashSet、HashMap、 Iterator)

ArrayList:实现了 List 接口的动态数组。

特点:

支持动态增长,可以存储可变数量的元素。

允许重复元素。

提供随机访问,通过索引快速访问元素。

适用于需要频繁访问和修改元素的情况。

HashSet:实现了 Set 接口的哈希集合,它基于哈希表实现。

特点:

不允许重复元素,自动去重。

不保证元素的顺序。

适用于查找和去重元素的情况。

HashMap:实现了 Map 接口的键值对哈希表。

特点:

存储键值对,可以通过键来获取值。

不允许重复的键,但允许重复的值。

不保证元素的顺序。

适用于需要键值对映射和快速查找的情况。

Iterator 接口:用于遍历集合元素的通用迭代器接口。

特点:

提供了 hasNext() 和 next() 方法,用于判断是否还有下一个元素并获取下一个元素。

可以在不同类型的集合中使用,例如 ArrayList、HashSet、HashMap 等。

可以使用增强型 for 循环(foreach)来简化遍历。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");

HashSet<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);

HashMap<String, Integer> map = new HashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);

// 使用 Iterator 遍历 ArrayList
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}

// 使用增强型 for 循环遍历 HashSet
for (Integer number : set) 
System.out.println(number);


// 使用 EntrySet 和 Iterator 遍历 HashMap
Iterator<Map.Entry<String, Integer>> mapIterator = map.entrySet().iterator();
while (mapIterator.hasNext()) {
Map.Entry<String, Integer> entry = mapIterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + ": " + value);
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值