第十章 接口、继承与多态
10.1 类的继承(extends关键字)
1.继承的基本思想是基于某个父类的扩展,制定出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。
2.可以在子类的构造方法中使用super()语句调用父类的构造方法,也可以在子类中使用super关键字调用父类的成员方法,但子类没有权限调用父类中被修饰为private的方法。
重写方法
3.继承也可以重写(也称覆盖)父类的成员方法。重写就是在子类中将父类的成员方法的名字保留,重写成员方法的实现内容,更改成员方法的存储权限,或修改成员方法的返回值类型。
3.重构(一种特殊的重写方式),子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同,唯一不同的是方法实现内容。
4.重写父类方法时,修改方法的权限只能从小的范围到大的范围改变。
5.子类重写父类可以修改方法的返回值类型,但重写的返回值类型必须是父类中同一方法返回值类型的子类。
6.当实例化子类对象是,父类对象也相应被实例化。换句话说,在实例化子类对象时,java编译器会在子类的构造方法中自动调用父类的无参构造方法。
7.实例化子类对象时,父类的无参构造方法被自动调用,但有参构造方法并不能被自动调用,只能依赖于super关键字显式地调用父类的构造方法。
10.2 Object类
在java中,所有的类都直接或间接继承了java.lang.Object类,它是所有类的子类,是java类层中的最高层类。1. getaClass()方法
它会返回对象执行时的Class实例,然后可使用getName()方法获取类的名字。
语法: getClass().getName();
2. toString()方法
将一个对象返回为字符串形式,它会返回一个String实例。实际应用中通常重写toString()方法,为对象提供一个特定的输出模式。3. equals()方法
equals()方法的默认实现是使用“==”运算符比较两个对象的引用地址,而不是对象的内容,所以想真正比较两个对象内容,需要在自定义类中重写equals()方法。10.3 对象类型的转换
1. 向上转型
就是将子类转型成父类,通过父类型引用指向子类型对象来实现动态调用。一个具体类到较抽象类之间的转换。 语句:Shape s = new Circle();2.向下转型
将抽象类转换为较具体类。向上转型是自动进行的,但是向下转型却不是,需要我们强制进行类型转换。这种方式称为显式类型转换。B b = new B();
A a = b;
B bb = (B)a;
3.分析
记住一个简单而又复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量,你可能说这个规则不对,因为父类引用指向子类对象时,最后执行的是子类的方法。其实这并不矛盾,那是因为采用了后期绑定(多态),运行时编译器又根据引用指向的实际类型去调用了子类的方法,而假若子类的这个方法在父类中并没有定义,则编译会出错。 当你使用父类引用指向子类对象的时候,其实jvm(java virtual machine)已经使用了编译器产生的类型信息调整转换了。这里你可以这样理解,相当于把不是父类中含有的方法从虚拟函数表中设置为不可见的,注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。10.4 instanceof判断对象类型
当程序执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型前需要判断父类对象是否为子类对象的实例。 这个判断通常使用instanceof操作符来完成。它可判断一个类实现了某个接口,也可以用来判断一个实例对象是否属于一个类。 语法: myobject instanceof ExampleClass//myobject某类对象引用;ExampleClass某个类10.5 方法的重载
方法重载:让方法名相同而形参不同的构造方法同时存在。同样也可以应用到非构造方法中。 class MethodOverloading {void receive(int i) {
} void receive(float f) { }void receive(int i,int j) {}} 重载中可以使两个方法返回值不同,但只有返回值不同并不可以区分两个方法重载,需要通过参数的个数以及参数类型来设置。
1. 不定长参数方法
语法: 返回值 方法名(参数数据类型···参数名称) 使用“···”形式定义不定长参数,编译器会将(int···a)这种形式看做是(int[]a),所以在add()方法体做累加操作时使用到for循环语句,循环中根据数组a的长度作为循环条件。 public static int add(int...a){int s=0;
for(int i=0;i<a.length;i++)
s+=a[i];
return s;
} public static void main(String args[]){
System.out.println("调用不定长参数方法:"+add(1,2,3,4,5,6,7,8,9));
}
10.6 多 态
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
10.7 抽象类与接口
10.7.1 抽象类(abstract关键字)
public abstract class Test{//定义抽象类 abstract void testAbstract();//定义抽象方法 } 1.抽象方法没有方法体,抽象类除了被继承外没有其它意义。 2.只要类中有一个抽象方法,此类就被标记为抽象类。 3.抽象类被继承后需要实现其中所有的抽象方法。10.7.2 接口
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法没有方法体。 1.定义接口(interface关键字): public interface drawTest{ void draw();//接口内的方法,省略abstract关键字 } 2.实现接口(implements关键字): public class Parallelogram extends Quadrangle implements drawTest{ ``` } 3.接口中定义的方法必须被定义为public或abstract形式。 4.在接口中定义的任何字段都自动是static和final的。接口与继承
java中不允许多个多重继承,但可以同时实现多个接口。 语法: class 类名 implements 接口 1,接口 2,···,接口 n第十一章 类的高级特性
11.1 Java类包
1.Java中每个接口或类都来自不同的类包。 2.一个完整的类名需要包名与类名的结合。如:java.util.Data 3.同一个包中的类相互访问,可以不用指定包名。11.1.1创建类包
类中定义包名的语法: package 包名 需将package表达式放置在程序第一行。当使用package关键字为类指定包名之后,包名将会成为类名的一部分,说明该类必须指定全名。 java包命名全部使用小写字母。11.1.2 导入类包(import关键字)
1.使用import关键字导入包 语法: import com.lzw.*;//指定com.lzw包中的所有类在程序中可以使用 import com.lzw.Math;//指定com.lzw包中的Math类在程序中可以使用 2.使用import导入静态成员 语法: improt static 静态成员11.2 final变量
1.final关键字用于变量声明,一但该变量被设定,就不可以再改变该变量的值。 语句: final double PI= 3.14; 2.final除了可以修饰基本数据类型的常量外,还可以修饰对象引用。 3.被定义为final的常量需要定义时使用大写字母命名,并且中间需要使用下划线进行连接。 4.被定义为final的对象引用只能指向唯一一个对象,不可以将它指向其他对象,但是一个对象本身的值却是可以改变的。通过将常量声明为static final,可使常量真正做到不可改变。 5.在Java中定义全局常量,通常使用public static final修饰。 6.将方法的参数定义为final类型,这预示着无法在方法中更改参数引用所指向的对象。11.3 final方法
1.方法定义为final类型可以防止任何子类修改该类的定义与实现方式,且效率要高于非final方法。 2.设置为private修饰符的方法子类无法访问,所以定义为private的方法隐式被定义为final类型,无需将private的方法再定义为final类型。11.4 final类
定义为final的类不能被继承,语法: final 类名{} 如果将某个类设置为final形式,则类中所有方法都被隐式设置为final形式,但final类中的成员变量可以被定义为final或非final形式。11.5 内部类
在类中再定义一个类,则将在类中再定义的那个类称为内部类。11.5.1 成员内部类
1.一个类中使用内部类可以在内部类中直接存取其所在类的私有成员。可以随意使用外部类的成员方法和成员变量。 2.内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。 3.外部类不可以直接访问内部类成员变量,内部类实例化操作必须在外部类或外部类的非静态方法中实现。 OuterClass out=new OuterClass(); OuterClass.innerClass in=out.doit();OuterClass.innerClass in2=out.new innerClass();
2.内部类向上转型为接口
1.如果将一个权限修饰符为private的内部类向上转型为其父类对象,或者直接向上转型为一个接口,在程序中就可以完全隐藏内部类的具体实现过程。仅留下一个接口和一个外部类,这是内部类最基本的用途。?2.非内部类不能被声明为private或protected访问类型:
对于个方法而言,他的上层是类,再上层是包,所以方法有由类继承得到的权限,由包"继承"得到的权限,和公共权限
而对于类而言,他的上层就是包,所以一个类只有"继承"自包的权限和公共的访问权限,并没有子类继承的概念
一个类要是有权限继承另一个类,那么要么他们同包要么那个类是public的,不然就已经没有机会访问了,更别提继承了,所以protected当中的子类部分是没有意义的,而剩下的同包,只需要默认权限就可以,所以用protected是多余的
3.使用this关键字获取内部类与外部类的引用
如果在内部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。public class TheSameName {内部类对象与外部类对象在内存中的分布情况:
private int x;
private class Inner{
private int x=9;
public void doit(int x){
x++;//调用形参x
this.x++;//调用内部类变量x
TheSameName.this.x++;//调用外部类变量x
}
}
}
11.5.2 局部内部类
可在类的方法中或任意的作用域中定义内部类。!方法中定义的内部类只能访问final类型的局部变量
因为java中规定,内部类只能访问外部类中的成员变量,不能访问方法中定义的变量,如果要访问方法中的变量,就要把方法中的变量声明为final(常量)的,因为这样可以使变量全局化,就相当于是在外部定义的而不是在方法里定义的11.5.3 匿名类
return new A(){ ```//内部类体 }; 匿名内部类编译后,会产生以“外部类名$序号”为名称的.class文件。在使用匿名内部类时,要记住以下几个原则:
·匿名内部类不能有构造方法。
·匿名内部类不能定义任何静态成员、方法和类。
·匿名内部类不能是public,protected,private,static。
·只能创建匿名内部类的一个实例。
·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
package hqs;
interface pr{
void show();
}
public class AdvancedPractice {
//2.在类中通过返回值为pr的方法中创建一个匿名内部类
public pr doit(){
return new pr(){
@Override
public void show() {
// TODO 自动生成的方法存根
System.out.println("匿名内部类2");
}
};
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println("主函数");
//1.直接在主函数中创建匿名内部类
new pr(){
public void show(){
System.out.println("匿名内部类");
}
}.show();
//2.实例化外部类,并通过doit()方法得到匿名内部类
AdvancedPractice ap = new AdvancedPractice();
pr pr1 = ap.doit();
pr1.show();
}
}
11.5.4 静态内部类
内部类前添加static,特点: 1.如果创建静态内部类的对象,不需要其外部类的对象 2.不能从静态内部类的对象中访问非静态静态外部类的对象。 3.非静态内部类不可以声明静态成员。11.5.5 内部类的继承
public class OutputInnerClass entends ClassA.ClassB{//继承内部类b
public OutputInnerClass(ClassA a){
a.super();
}
}
class ClassA{
class ClassB{
}
}
第十二章 异常处理
12.1 异常概述
1.异常是一个在程序执行期间发生的事件,它中断了正在执行的程序的正常指令流。2.Java语言的异常捕获结构由try、catch和finally3部分组成。 语法:
try{
//程序代码块
}
catch(Exceptiontype1 e){
//对Exceptiontype1的处理
}
catch(Exceptiontype2 e){
//对Exceptiontype2的处理
}
···
finally{
//程序块
}
12.2 Java常见异常
12.3 自定义异常
用户自定义异常,只需要继承Exception类。步骤:1.创建自定义异常类2.在方法中通过throw关键字抛出异常对象3.可通过try-catch语句捕获并处理,或在方法的声明处通过throws指明要抛出给方法调用者的异常4.捕获并处理12.4 在方法中抛出异常
1.throws关键字
通常应用在声明方法,用来指定方法可能抛出的异常。多个异常用逗号隔开。2.throw关键字
通常用于方法体中,并抛出一个异常对象。程序执行到throw语句时立即终止。12.5 运行时异常
RuntimeException异常是在程序运行过程中产生的。异常类结构:
第十三章 Swing程序设计
13.1 Swing概述
1.JAVA1.0中基础类AWT(抽象窗口工具箱)并没有达到构建通用GUI使能够在所有平台上运行,于是有了Swing,它是AWT组件的增强版。 2.Swing组件为“轻量级组件”,不依赖于操作系统,可以在任何平台上运行; AWT组件为“重量级组件”,它依赖于本地平台的窗口系统来决定组件外观、风格等。1.Swing组件的继承关系
Swing组件中大多数GUI 组件都是Component类的直接子类或间接子类。 java关于窗口组件的编写,都与组件以及容器的概念相关联。
13.2 常用窗体
13.2.1 JFrame窗体
1.JFrame窗体是一个容器,它是Swing程序中各个组件的载体,可以将JFrame看作是承载这些Swing组件的容器。 2.语法格式: JFrame jf = new JFrame(title); Container container = jf.getContentPane(); 3.通过调用getContentPane()方法将窗体转换为容器,然后在容器中添加组件或设置布局管理器。 如:container.add(new JButton("按钮")); 4.也可将组件从容器中删除:container.remove(new JButton("按钮")); 5.构造方法: public JFrame() public JFrame(String title) //title窗体标题 窗体框显示的方法:jf.setVisible(true); //显示对话框,不建议使用show(),使用setVisible(true)1.窗体关闭方式
调用setDefaultCloseOperation()方法关闭窗体。常用方式有以下4种: 1.DO_NOTHING_ON_CLOSE //什么都不做将窗体关闭 2.DISPOSE_ON_CLOSE //任何注册监听程序对象自动隐藏并隐藏窗体 3.HIDE_ON_CLOSE //隐藏窗口的默认窗口关闭 4.EXIT_ON_CLOSE //退出应用程序默认窗口关闭 jframe.dispose() 方法,关闭窗口,与点击右上角的X的功能一样。如果之前对jframe注册过窗口事件,那么也会触发其监听器。13.2.2 JDialog窗体
是对话框,功能是从一个窗体中弹出另一个窗体。与JFrame类似。 构造方法: public JDialog();public JDialog([Frame f]);
public JDialog([Frame f],[boolean model]);
public JDialog([Frame f],[String title]);
public JDialog([Frame f],[String title],[boolean model]);//[]表示可以不是必须存在,参数依次为指定父窗体、标题和模式
13.3 标签组件与图标
13.3.1 标签(JLable)
由JLable类定义,父类为JCompomemt类 标签可以显示一行只读文本、一个图像或带图像的文本,并不能产生事件 构造方法: public JLable();public JLable(,Icon icon);
public JLable(String text,int aligment);
public JLable(Icon icon,int aligment);
public JLable(String text,Icon icon,int aligment);//创建一个带文本、带图标的JLable对象,并设置标签内容的水平对齐方式
13.3.2 图标的使用
1.创建图标 通过Icon接口来创建图标,可以在创建是给定图标的大小、颜色等特性。如果使用Icon接口,必须实现下面3个方法: public int getIconHeight() //获取图标长 public int getIconWidth() //获取图标宽 public void paintIcon(Component arg0,Graphics arg1,int arg2,int arg3)//用于实现在指定坐标位置画图2.使用图片图标
利用javax.swing.ImageIcon类根据现有图片创建图标
构造方法:
public ImageIcon(); //调用setImage(Image image)方法来添加图片
public ImageIcon(Image image);
public ImageIcon(Image image,String description);//description添加简单描述
public ImageIcon(URL url); //利用计算机网络图片
13.4 常用布局管理器
13.4.1 绝对布局
硬性指定组件的容器中的位置和大小,可以使用绝对坐标的方式指定组件位置 步骤: 1.使用Container.setLayout(null)方法取消布局管理器 2.使用Component.setBounds()方法设置每个组件的大小与位置13.4.2 流布局管理器(FlowLayout)
从左到右摆放组件,直到占据一行则向下移动一行。13.4.3 边界布局管理器(BorderLayout)
可将容器分为东西南北中5个区域。将组件加入这5各区域中。主要成员变量: BorderLayout.NORTH(SOUTH、EAST 、WEST、CENTER) //组件置于顶端(底、右、左、中间)
13.4.4 网格布局管理器
将容器划分为网格,组件按行列进行排列。 构造方法: public GridLayout(int rows,int columns) //int rows,int columns:行,列 public GridLayout(int rows,int columns,int horizGap,int vertGap)//horizGap,水平间距。vertGap,垂直间距13.5 常用面板
面板可以作为容器容纳其他组件,但它必须被添加到其他容器中1 JPanel面板
2.JScrollPane面板,带滚动条。
JScrollPane只能放置一个组件,不可以使用布局管理器。若放置多个组件,可将多个组件放置在JPanel面板上,再将JPanel作为整体添加到JScrollPane上。
13.6 按钮组件
1.提交按钮(JButton) 构造方法:public JButton([String text],[Icon icon])//显示文字,图标 2.单选按钮组件(JRadioButton) 构造方法:public JRadioButton([String text],[Icon icon],[boolean selected] )//设置文字、图标以及默认是否选中 ButtonGroup类用于产生按钮组。3.复选框组件(JCheckBox)
13.7 列表组件
13.7.1 下拉列表框组件
1.JComboBox类 2.JComboBox模型 为接口,两种实现方法: public void setSelectedItem(Object item) //设置下拉列表框选中项 public Object getSelectedItem() //返回下拉列表项中选中项还可以继承AbstractListModel类两个重要方法:
getSize():返回列表长度
getElementAt(int index):返回指定索引处的值
13.7.2 列表框组件JList类()
构造方法:public void JList() 对列表框中项目设置有三种方式:数组、Vector类型和ListModel模型13.8 文本组件
1.文本框组件(JTextField)
用来显示或编辑一个单行文本 构造方法:public JTextField([Document docModel],[String text],[int fieldWidth])//设置默认文字,文本框长度2.密码框组件(JPasswordField)
构造方法:public JPasswordField([Document docModel],[String text],[int fieldWidth])
方法setEchoChar(),可以改变密码框回显字符
获取密码框文字的方法:getPassword(); //java中不建议使用getText();方法。
3.文本域组件(JTextArea)
可输入多行文字
构造方法:public JTextArea([Document docModel],[String text],[int fieldWidth])
13.9 常用事件监听器
实质是“实现特点类型监听器接口”的类对象。事件用对象表示。 所有事件源都具有addXXXListener()和removeXXXListener()方法,为组件添加或移除相应事件监听器1.动作事件监听器(ActionListener)
一般为事件源做监听事件时使用匿名内部类形式2.焦点事件监听器(FocusListener)
实现接口FocusListener,需重新foucusLost()与focueGained()方法第十七章 枚举类型与泛型
17.1 枚举类型(enum)
1.是一种基本数据类型而不是构造类型,它用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型。 语法如下: enum <枚举类型名> {<枚举表>}; 该语句以enum保留字开始,接着为枚举类型名,它是用户命名的一个标识符,以后就直接使用它表示该类型,枚举类型名后为该类型的定义体,它是由一对花括号和其中的枚举表所组成,枚举表为一组用逗号分开的由用户命名的符号常量,每个符号常量又称为枚举常量或枚举值。例:public enum Constants{ Constants_A,Constants_B}
enum color{red, yellow, blue};
2.枚举类型可以看做一个类,它继承了java.lang.Enum类,当定义一个枚举类型时,每个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员默认都被final、public、static所修饰。 3.枚举类型常用方法: values(),将枚举型的成员变量实例以数组的形式返回。 valueOf,可将普通字符串转换为枚举类型 compareTo(),用于比较两个枚举类型对象定义时的顺序 ordinal(),用于获取某个枚举对象的位置索引值 4.在枚举类型中可以添加构造方法,但规定构造方法必须为private修饰符所修饰。