Java初学随手记
固定套路
输入输出:
Scanner in = new Scanner(System.in);
foot = in.nextInt();
inch = in.nextDouble();
System.out.println("foot=" + foot + ", inch=" + inch);
变量类型
浮点数不能精确计算
强制类型转换:(int)(inch/12.0),其中(int)是单目运算符,优先级很高,所以后面要注意加括号。
计算的优先级
单目运算符优先级高于双目运算符。
结合顺序:一般从左到右,赋值从右到左。
关系运算(大于小于等于):判断是否相等的==和!=的优先级比其他的低, 连续的关系运算从左到右进行。
关系运算中,true和false二者不能比大小,也不能与数字比大小;整数可以与浮点数比较大小;浮点数比较大小可能会不精确,如果需要比较,可以比较差值是否小于极小量。使用Math.abs()
基本结构中的一些注意事项
else总是和离得最近的那个if进行配对,并不会考虑缩进格式。除非用{},所以不如总是加上{}。
级联的判断语句和多路分支均可用于java。
java和C语言的一大区别是布尔值和整型进行了区分,所以条件语句括号里忘记要写==时就会报错。
面向对象
对象
对象 = 属性 + 服务
对象变量是对象的管理者,而非所有者。
调用函数
通过.运算符来调用某个对象的函数。
在成员内部直接调用自己(this)的其它函数,可以加this.也可以不加。
本地变量(定义在函数内部的变量)的生存期和作用域都是函数内部。
成员变量的生存期是对象的生存期,作用域是类内部的成员函数。
对象初始化
成员变量初始化默认是0或null。
构造函数:如果有一个成员函数的名字和类的名字完全相同,则在创建这个类的每一个对象的时候就会自动调用这个函数。这个函数不能有返回类型。(名字和类名相同,在构造时被自动调用,无返回类型)
创建对象时发生的事情:先执行成员变量的初始化,再执行合适的构造函数。
重载:构造函数可以有多个,但参数表必须不同(可以有参数,也可以没有参数),在创建对象时就会自动根据所给的参数选择符合的构造函数去调用。
构造函数还可以互相调用。只能使用一次,只能出现在第一句,只能出现在构造函数里。(如在第一句写this()就可以先调用那个没有参数的构造函数,再接着进行下面的操作)
访问属性
封装:把数据和对数据的操作放在一起。
封闭的访问属性
private只能用于成员变量和成员函数前面,表明私有,只有类中的定义初始化的地方和成员函数中才能被使用。
private只有这个类的内部(类的成员函数和定义初始化)可以访问,这个限制是对类的而不是对对象的。
如果想要更改这个属性,可以在类里写一个public的成员函数来改变它,同时方便被外界调用。
开放的访问属性
public
如果没有写private或public,那么它就是friendly的,位于和它同一个包的可以访问。
另外还有protected,与继承有关。
一个.java文件是一个编译单元,其中可以包含多个class,但是一个文件中只能有一个是public class,而且文件名与类名相同。
包package
import package.class
通过文件夹的层级来体现和管理。
类变量和类函数static
static:类里面自带的变量/函数,不是对象中的变量/函数。类的变量和函数构造时间早于对象的。在类装载的时候就进行操作了。
接口设计
泛型容器类
链表、集合和哈希表
ArrayList<String> notes = new ArrayList<String>();
HashSet<String> notes = new HashSet<String>();
HashMap<Integer, String> coinnames = new HashMap<Integer, String>();
只要在类中包含了toString函数,就可以直接输出。
对象数组
对象数组中的每个元素都是对象的管理者而非对象本身。
普通数组中的for each循环:
int[] ia = new int[10];
for(int i=0; i<ia.length; i++){
ia[i] = i;
}
for(int k : ia){
System.out.println(k);
}
在普通数组的for each循环中的k只是原值的复制品。
但是在对象数组中则会改变原值。
因为对象数组中存的是“指针”。(很像C语言)
继承
多态
多态变量
Java的对象变量是多态的,可以保存不止一种类型的对象。
可以是声明类型的对象,或声明类型的子类的对象。
当把子类的对象赋给父类的变量的时候,就发生了向上造型。
静态类型(声明类型)与动态类型
造型cast
类型转换与造型不同,类型转换是真的改了类型,造型只是把它当做这个类型来对待,所以造型不一定是安全的。
当将子类当做父类看待时,就叫做向上造型,而且总是安全的。
函数调用的绑定
当通过对象变量调用函数时,应该调用哪个函数?
静态绑定:根据声明类型来决定
动态绑定:根据动态类型来决定(Java默认)
覆盖override
子类和父类中存在名称和参数表完全相同的函数,这一对函数构成覆盖关系。
调用时会调用变量当时管理对象(动态类型)所属的类当中的函数。
Object类
Java单根结构:所有的类都是继承自Object的
toString
equals
@override
实战:解决问题
消除复制代码
增加函数,进行多次调用
增加可扩展性
用封装来降低耦合
类和类之间关系要小,相互独立!
类自己的事情尽量自己干,不要把信息都告诉别人让别人代劳。
用StringBuffer来减少字符串的改变对系统资源的消耗(字符串是不可变的,每次修改就需要建一个新的)
用接口实现聚合
改变硬编码:用容器(如HashMap)来承载可选项,而不是遍历
以框架+数据
抽象abstract
关于“抽象”
与具体相对:表示一种概念而非实体
与细节相对:在一定程度上忽略细节而着眼大局
抽象类与抽象函数
抽象类:表达概念而无法构造出实体的类(不能产生对象,但是可以定义变量)
抽象函数:表达概念而无法实现具体代码的函数
抽象函数的“实现”
继承自抽象类的子类必须覆盖父类中的所有抽象函数,除非子类也是抽象类。
一些程序编写经验
数据与表现分离
程序的业务逻辑与表现无关
表现可以是图形的,也可以是文本的。
表现可以是当地的,也可以是远程的。
责任驱动的设计
分工明确,每一个类只做自己擅长做的事情。
网格化
图形界面本身有更高的解析度,但是将画面网格化后,数据处理变得更容易。
接口interface
接口是纯抽象类:所有成员函数都是抽象函数,所有成员变量都是public static final
接口只规定了长什么样,但是不管里面有什么。
类:extends 接口:implements
面向接口的编程方式
设计程序时先定义接口,再实现类
任何需要在函数间传入传出的一定是接口,而不是具体的类
关于Swing
布局管理器
Swing:部件和容器
自动计算,保证了放缩时一定能看到
反转控制(Swing的消息机制)
内部类
定义在别的类内部或函数内部的类
内部类能直接访问外部的全部资源:包括任何私有的成员;外部是函数时,只能访问那个函数里final的变量
匿名类
在new对象的时候给出的类的定义形成了匿名类
匿名类可以继承某类,也可以实现某接口
Swing的消息机制广泛使用匿名类
JTable
以表格形式显示和编辑数据,但本身不存储数据。(数据与表现分开)
MVC设计模式
model:接受数据修改,并通知view刷新
view:从model获得数据来刷新整个页面显示
control:调用model的接口来修改其中的数据
control和view没有联系,用户在界面上所做的操作不直接改变屏幕显示的内容
好处:每个部分都比较独立,低耦合
control和view经常会合并在一个类中,但彼此还是独立的。
捕获异常
通过try, catch, throw等关键字来对异常进行处理。