Java基础-持续更新
基础未整理
- 本地变量是函数内部定义的,必须初始化;成员变量可以不初始化,在创建对象时会默认赋值为0值(null)。
- 函数重载——函数名相同,重新载入参数。
- private是针对类来说的,并不是针对某一个对象。无特殊情况,成员变量都应以为private。
- 如果旨在成员函数前未加public或private,也就是default(friendly),其作用域为同一个包(package)
- 一个.java文件是一个编译单元,一个编译单元可以有很多java类,但最多只能有一个类是public,这个类名必须和文件名相。其余没有public的类只能在这个包里调用。
包
- 包:包的名字对应文件系统中目录的名字,.java文件的名字就是public类的名字。
- import一个包相当于C++中的include。
- import时尽量具体到包中的某个类,防止包中有同名类。
- 包中也可以放另一个包,如java.util.Scanner。
static(类变量、类函数)
- 一个类中类变量只有一个,它属于类本身所有,因此可以Display.step。当被一个对象改变此静态变量(类变量)时,其他对象所见的变量值也改变。
- 对类变量的在编译时进行初始化,只做一次,和对象的创建没有关系。初始化顺序:1.先按照静态成员变量的定义顺序在类内部声明成员变量。2.再按照原java类中对成员变量的初始化顺序进行初始化。
- 类函数也是一样,只属于类,并且里面只能访问类变量和类函数。
设计类
- 人机交互+业务逻辑,分离。
- 先设计业务接口(可能存在哪些操作),然后去设计接口所操作的数据采用什么数据结构(容器)
- 采用框架,把硬编码改为 框架(数据结构+接口)+数据 的结构。
泛型容器类
- 用于存放元素,
对象数组(String[])
- String关键字,声明一个字符串对象的管理者(类似指针),声明后默认值是null;而int声明一个数值,声明后默认值是0。
- for-each循环【for(int k : ia)】,拿出来的每一个k都是一个复制品;对于对象数组(String[]),初始化会创建多个管理者,但并没有指向的String,在for-each中,会创建一个复制品也指向那个String。
- 对于容器类(ArrayList),for-each循环也可用。
ArrayList
- java.util.ArrayList
Set(集合)
- 无重复,无续
- 当类有public String toString()函数时,容器可以直接输出(对象直接调用):println(s);
Hash Table
- <key, value>对应,容器里面所有东西都应该是对象,不能是基本元素。key时唯一的。
- get()取得value。
继承
- 子类从父类继承了private变量,但是不能直接使用;解决方法:1->变量改为protected,此时子类能访问父类成员变量了,而其他类不能访问。2->在父类里面作初始化,在子类中用super()将成员变量传过去。3->子类可以通过父类的方法来操作父类的成员变量。
- 构造子类对象,先做父类初始化(顺序为:定义初始化、构造器),在完成子类初始化。
- super()用来传递参数给父类构造器,如果子类没写super,则默认调用父类没有参数的构造器。super. 可以直接调用父类的函数。
- 子类的对象可以被当作父类的对象来使用:
- 赋值给父类变量;
- 传递给需要父类对象的函数;
- 放进存放分类对象的容器里。
多态
多态变量
- java的对象变量是多态的,它们能保存不止一种类型的对象。
- 具体某个时刻变量类型是多种形态的:静态类型(声明的类型)和动态类型(运行到此时的类型,子类对象)。
- 向上造型:把子类的 对象 赋给父类 变量 ,反之不行。
- 注意:java中不存在对象赋值给对象!!!赋值并不是把一个对象copy一份给另一个对象(或者替换),而是让两个管理者去管理同一个对象。对象和管理者的关系,这点不同于C++!
- 例如:String s = “hello” 创建一个String类型的对象“hello”,并声明一个管理者s来管理它。
- Cast造型转换只是当作另一个类型来看待,并不是强行改造。
函数的多态
- 函数调用的绑定:当通过对象变量调用函数的时候,调用哪个函数这个事件叫作绑定(对象和哪个函数绑定)。
- 静态绑定:根据变量的声明类型来决定,编译时就知道。
- 动态绑定:根据变量的动态类型来决定,运行时才知道。
- 在成员函数中调用其他成员函数,是通过this对象变量来调用的。
- 覆盖(override):子类和父类函数的名字和参数表完全相同的函数,且必须都是public,父类的变量调用存在覆盖关系的函数时,会调用当前变量所管理的对象所属类的函数。
- 对象——方法,类——函数。???
Object类
- 是所有类的root类,
- Object类的函数:
- toString()
- equals(),判断两个变量是否管理同一个对像
- 向下造型,CD.cc = (CD)obj;
抽象
- Abstract抽象类,提供一个方法(接口),在父类中并不去实现, 由子类去将抽象化为具体。抽象函数后面不加{},
- 有抽象函数的类也必须是抽象的,抽象类不能产生对象(不能进行实例化)。但是可以用抽象类的名字来定义变量,付给这个变量的一定是该类的非抽象子类对象。用父类变量来管理子类对象。
- 抽象函数——表达概念而无法实现具体代码的函数。
- 抽象类——表达概率而无法构造出实体的类。
- 继承自抽象类的子类必须覆盖(实现)父类中的抽象函数,否则自身就成为抽象类,也不能制造对象。
程序设计
- 数据和表现分离:程序的业务逻辑和表现(图像or文本,本地or远程)无关。
- 责任驱动的设计:程序的功能应该分配给哪个类实现,每个类做自己擅长的东西(和自己拥有的数据相关的操作或者方法)
接口
- 解决java中多对多的继承问题。
- 接口是纯抽象类,表达的是一个概念。所有成员函数都是抽象函数,所有的成员变量都是public static final,不属于任何对象且不会被改变。
- 接口规定了长什么样,但不管里面有什么。
- interface是一种特殊的类,不能被直接实例化,必须有一个类来实现该接口,然后实现其方法,才可以被实例化。
- 类继承类用extends,类实现接口用implements。
- 类可以实现很多接口,接口不能实现接口
- 接口可以继承接口,但不能继承类
- 设计程序时,先定义接口,在实现类,任何需要在函数间传入传出的一定是接口而不是类,接口——两个类连接的空白概念关口——包装盒
消息机制
反转控制(注入反转)
- JButton类中有ActionListener的接口,这个接口相当于一个包装盒,本地实现一个ActionListener的对象,并将要实现的本地函数放进去(将函数指针打包),然后在JButton中注册,当按下按钮时就可以执行本地的函数了。
内部类
- 内部类是一个内部的成员,和其他成员一样。可以自由访问类中的成员。
- 内部匿名函数 :new ActionListener{…},大括号定义了一个匿名的类,并实现了ActionListener接口, 然后用new制造了这个类的对象。
- 在new对象时给出类的定义,形成匿名类。匿名类可以继承某类,也可以实现某接口。 Swiing的消息机制广泛使用匿名类。
- 内部类:1.类的内部的,2.函数的内部的。内部类可以直接访问外部的全部资源,1.包括任何私有变量,2.外部是函数时,只能访问那个函数的final变量。
MVC设计模式(JTable)
- 数据(Model)、表现(View),控制(Control)三者分离。
- 模型:保存和维护数据,提供接口让外部修改数据,通知表现需要刷新。
- 表现:从模型获得数据并画出。
- 控制:从用户得到输入,并根据输入调整数据。
异常
try{
可能发生异常的代码快}
catch(可能的异常类型 变量)
{对异常的处理代码块}
catch(可能的异常类型 变量)
{对异常的处理代码块}
finally {进入try必须执行的语句}
- 搜寻至上层main函数,寻找是否有对存在异常代码块(函数)的异常处理。
- 若捕捉到了异常,但在这个代码层不能解决,可以再度抛出 throw e ,后面还能捕获该异常;若未抛出,则说明已处理该异常。
- finally,只要进了try,无论如何退出的,在离开try之前,都会执行finally。
- 异常机制最大的优势:清晰地分开了业务正常逻辑代码和遇到问题时的处理代码。
- 异常声明:如果函数可能抛出异常,就必须在函数的头部加以声明。声明后必须把函数的调用放到try块中,并设置catch来捕捉,或者再抛出此处无法处理的异常。
class OpenException extends Throwable { }
void f() throws OpenException, CloseException {
...
throw new OpenException();
}
-
异常+继承:
- 当Override一个函数的时候,子类不能声明抛出比父类的版本更多的异常,因为可能通过父类的变量管理子类。但可以不抛出异常。
- 在子类的构造函数中,必须声明父类可能抛出的全部异常,因为在构造时会调用父类的构造函数。也可以声明自身可能抛出的异常。
-
能throw的对象继承自Throwable类,Exception类也继承自Throwable。
-
Exception的常用构造
throw new Exception();
throw new Exception("OpenException");
- 异常捕捉:抛出子类的异常可以被捕捉父类异常的catch捕捉到。如catch(Exception e){…}可以捕捉继承自其的任何异常。
- 运行时刻异常:由系统自带了,像ArrayIndexOutOfBoundsException这样的异常不需要声明。
- 如果没有任何机制来捕捉异常,当发生时程序就会终止。
流
- 流的基础类:InputStream, OutputStream.
- 文件字节流:FileInputStream,FileOutputStream
- 对文件数据以字节的形式进行读写操作
- 所有的输入输出流都有Exception,需要用try。
- 过滤器流
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream( //缓冲流
new FileOutputStream("a.dat")));
int i = 123456;
out.write(i);
- DataOutputStream用于写入二进制方式表达的基本数据类型数据。
- 文本流:
- 二进制数据(字节流)采用InputStream、OutputStream,通常处理.dat文件等;
- 文本数据(字符流)采用Reader、Writer,通常处理.txt文件等。
- 在流上建立文本处理
//写入文件
PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter( //流到二进制数据转换
new FileOutputStream("abc.txt"))));
//读文件
BufferedReader in = new BufferedReader(
new InputStreamReader(
new FileInputStream("Main.java")));
String line;
while((line = in.readline()) != null){
System.out.println(line);
}
- 缓冲流BufferedInputStream与BufferedOutputStream
- 因为内存读写速度远高于磁盘等介质的处理速度,为了高效利用内存,建立了缓冲流
- 从磁盘读写的数据先放到缓冲区,待其满后再一次性处理。
- BufferedWriter和BufferedReader
- BufferedReader读取字符文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取。write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去
- BufferedWriter写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
- PrintWriter(没有PrintReader)
- 功能和BufferedWriter相似,继承自java.io.Writer,是文本写入字符输出流,但PrintWriter具有自动行刷新,其println方法自带换行操作,常用语Socket通信,因为往Socket写入的通常是字符数据。
- InputStreamReader与OutputStreamWriter
- InputStreamReader,自下而上 读,字节流->字符流
- OutputStreamWriter,自上而下 写,字符流->字节流
- 可以指定字符的编码方式,用utf-8还是GB18030(eclipse默认)。
- 文本输入输出
- 输出
- format(“格式”,…)
- printf(“格式”,…)
- print(各种基本类型)
- println(各种基本类型)
- 输入
- Scanner:在InputStream或Reader上建立一个Scanner对象,可以从流的文本中解析出各种基本数据类型,采用 next…()
- 输出