接口与实现
1.接口与抽象类的区别
答:
A:成员的区别
抽象类:
构造方法:有构造方法,用于子类实例化使用。
成员变量:可以是变量,也可以是常量。
成员方法:可以是抽象的,也可以是非抽象的。
抽象方法和成员变量可以是public、protected和包权限
接口:
构造方法:没有构造方法
成员变量:只能是常量。默认修饰符:public static final
成员方法:jdk1.7只能是抽象的。默认修饰符:public abstract (推荐:默认修饰符请自己永远手动给出)
jdk1.8可以写以default和static开头的具体方法
B:类和接口的关系区别
类与类:
继承关系,只能单继承。可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
类还可以在继承一个类的同时实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。
C:体现的理念不同(抽象类表示这个对象是什么,接口表示这个对象能做什么)
抽象类里面定义的都是一个继承体系中的共性内容。
接口是功能的集合,是一个体系额外的功能,是暴露出来的规则。
[在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)]
接口是粗略的技术规范,抽象类对粗略的技术规范作了一些简单的说明。
2.什么是接口。
答:一种用于描述类对外提供功能规范的、能够多重继承的、特殊的抽象类。
接口是类与类之间连接的通道。类之间没有直接的接触,它们通过接口互通信息,从而实现类与类之间的资源交互。
3.接口的用途有哪些。
答:用途之一:实现多重继承。
用途之二在于它是一种规范,它规定了一组类在实现某些功能时必须拥有的统一规则,它屏蔽了相关功能的实施细节,以一种标准模式即接口方式提供给外部类或系统使用。
4.什么是接口的回调。
答:把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量,该接口变量就可以调用被类实现的接口方法以及接口提供的default方法或类重写的default方法(接口变量无法调用类中的其他非接口方法)。
5.为什么要定义接口。
答:某些现实问题需要用多重继承描述,但又不适合放在父类中;Java中的类只能单继承
(类的多重继承能够导致方法调用的冲突);Java中的接口可以多重继承
(接口中不存在具体方法,不会引起方法调用的冲突)。
6.面向接口编程的核心思想。
答:面向接口编程是指当涉及某个重要的类时不让该类面相具体的类,而是面向接口,即所设计类中的重要数据是接口生命的变量,而不是具体类声明的变量。其核心思想为:使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。
7.什么是函数接口。
答:如果一个接口中有且只有一个abstract方法,称这样的接口为单接口(函数接口)。
8.简述接口回调Lambda表达式实现的接口方法机制。
答:对于函数接口,允许把Lambda表达式的值(方法的入口地址)赋值给接口变量,那么接口变量就可以调用Lambda表达式实现方法(即接口中的方法)。
9.什么是接口参数。
答:如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。
内部类与异常类
1.内部类与外嵌类的关系。
答:内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
内部类的类体不可以声明类变量和类方法(why),外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。
内部类仅供它的外嵌类使用,其他类不可用某个类的内部类声明对象。可以用protected和private修饰内部类(不可修饰非内部类),因为内部类仅供它的外嵌类使用,是否使用访问修饰对内部类没有实际意义。
内部类的外嵌类的成员变量在内部类中有效,使得内部类和外嵌类的交互更加方便。
2.为什么内部类的类体不可以声明类变量和类方法,却可以有常量。
public class InnerClassDemo{
int x;
class A{
static int a = 0;//这样写是不合法的.
static final int b=0;//这样写是合法的,常量
}
}
答:java类加载顺序,首先加载类,执行static变量初始化,接下来执行对象的创建,如果我们要执行代码中的变量int a 初始化,那么必须先执行加载外部类,再加载内部类,最后初始化静态变量 a ,问题就出在加载内部类上面,我们可以把内部类看成外部类的非静态成员,它的初始化必须在外部类对象创建以后进行,要加载内部类必须在实例化外部类之后完成 ,java虚拟机要求所有的静态变量必须在对象创建之前完成,这样便产生了矛盾。
java常量放在内存中常量池,它的机制与变量是不同的,编译时,加载常量是不需要加载类的,所以就没有上面那种矛盾。
3.静态内部类有哪些特点。
答:只有内部类可以是static类,非内部类不可以是static类。static内部类是外嵌类中的一种静态数据类型,程序可以在其他类中使用static内部类来创建对象。但static内部类不可以操作外嵌类中的实例成员变量。
4.什么是匿名类,匿名类有哪些特点。
答:匿名类分为和子类有关的匿名类、和接口有关的匿名类。
和子类有关的匿名类:(父类的构造方法+子类的类体)
java允许用户直接使用一个类的子类的类体创建一个子类对象,即创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类。
和接口有关的匿名类:(接口名+实现该接口的类体)
java允许用户直接用接口名和一个类的类体创建一个匿名对象,此类体被认为是实现了接口的类去掉类声明后的类体,称作匿名类。(不要求是函数接口,即单接口)
ps:和接口有关的匿名类以及用lambda表达式代替匿名类都发生在为接口变量赋值或向接口类型的形参传值。
匿名类的特点:
匿名类可以继承父类的方法,也可以重写父类的方法。
在使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。
匿名类可以访问外嵌类中的成员变量和方法,在匿名类中不可声明static变量和方法。
由于匿名类是个子类,没有类名,所以在用匿名类创建对象时要直接使用父类的构造方法。
5.匿名内部类可以是抽象类吗。
答:匿名内部类不能是抽象类,因为定义匿名内部类时立即生成对象,而抽象类不允许生成对象。
6.什么异常。
答:也称例外,表示程序运行中出现意外情况的一个信号。异常是特殊的运行错误对象,一旦产生就会中断程序的正常执行。
7.java异常处理的五个关键字及其作用。
答:try:执行可能产生异常的代码
catch:捕获异常
finally:无论是否发生异常,此处代码总能执行
throws:声明异常,声明方法可能抛出的各种异常
throw:抛出异常,手动抛出异常
8.java如何处理异常。
答:当程序遇到运行时错误时,会产生并抛出一个信号(异常);
通过try/catch语句捕获这个信号(异常);
根据这个信号(异常)的不同进行相应的处理。
9.java的异常处理机制。
答:异常的定义(异常类)
异常的抛出(throw)
异常的捕获处理(try-catch)
异常的声明/报告(throws)
10.简述java的异常声明(异常报告)。
答:一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明异常。
如果一个方法中存在未处理的异常,则需要在该方法头上用throws关键字声明该异常。
通过异常声明可以将异常报告给方法的调用者。
RuntimeException及其子类的异常可以不声明。
11.断言语句是什么,作用有哪些。
答:断言语句用于调试代码阶段。在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程又需要调试,可以重新启用断言语句。
使用关键字assert声明一条断言语句,断言语句有以下两种格式:
assert booleanExpression;
assert booleanExpression:messageException;
注:booleanExpression的值必须为布尔型的表达式;messageException可以是字符串的表达式,当booleanExpression的值为false时,程序从断言语句处停止执行,并输出messageException。
常用实用类
1.Scanner分解字符序列中的单词的步骤和方法。
答:Scanner可以调用useDelimiter(正则表达式),将正则表达式作为分隔标记,如果不指定标记,则默认调用空白符。
Scanner对象调用next()方法以此返回被解析的字符序列中的单词,如果最后一个单词已被next()返回,Scanner对象调用hasNext()将返回false否则返回true。
对于被解析的数字型单词,可以调用nextInt()、nextDouble()方法将数字型单词转化为int或double数据返回。
如果单词不是数字型单词,Scannr对象调用nextInt()或nextDouble()方法将会发生InputMismatchException异常,在处理异常时可以调用next()方法返回非数字化单词。
2.StringTokenizer分解字符序列中的单词的步骤和方法。
答:和split()方法不同的是,StringTokenizer对象不使用正则表达式作为分隔标记。
StringTokenizer(String s):为String对象s构造一个分析器,使用默认的分割标记,即空格符、换行符、回车符、tab符、进纸符作分隔标记。
StringTokenizer(String s,String delim)参数delim中的任意字符排列被作为分隔标记。
3.StringTokenizer和Scanner的区别以及如何使用正则表达。
答:使用StringTokenizer,Scannner类都可以分析字符串,获取字符串中被分隔符分隔的单词。StringTokenzier类把分解出的全部单词都存放到StringTokenzier对象的实体中,因此,StringTokenzier对象能较快速度获取单词,即StringTokenzier对象的实体占用较多的内存(即用空间换取内存)
Scanner类不把单词存放到Scanner对象实体中,而是仅仅存放怎样获取单词的分隔标记,即Scanner获取单词的速度相对较慢,但节省内存空间(即以速度换取空间)
StringTokenzier对象一旦诞生就立刻可以知道单词的数目,既可以用countTokens()返回单词数目,而Scanner不提供这样的方法,因为Scanner类不把单词存放到Scanner对象的实体中,如果想要知道单词的数目,就必须一个一个去或取。
StringTokenizer类对象不使用正则表达式做分隔标记,Scanner对象调用useDelimiter(正则表达式)将正则表达式作为分隔标记。
4.StringBuffer类与String类的主要区别。
答:String对象的字符序列是不可修改的,也就是说,String对象的字符序列的字符不能被修改、删除,即String对象的实体是不可以再发生变化的。
StringBuffer类的对象的实体的内存空间可以自动地改变大小,便于存放一个可变的字符序列。(有三个构造方法)
5.常量折叠是什么意思。
答:常量折叠是一种编译器优化技术;常量折叠主要指的是编译期常量加减乘除的运算过程会被折叠。
6.java的反射技术是什么。
答:Class是java.lang包中的类,Class的实例封装和类有关的信息(即类型信息)。任何类默认有一个public的静态的(static)Class对象,该对象的名字是class(用关键字做了名字,属于java系统特权),该对象封装当前类的有关信息(即类型的信息),如该类有哪些构造方法,哪些成员变量,哪些方法等。也可以让类的对象调用getClass()方法(从java.lang.Object类继承的方法)返回这个Class对象:class。
Class对象调用方法可以获取当前类的有关信息,比如,类的名字、类中的方法名称、成员变量的名称等等,这一机制也称为Java反射。
7.Class的类中方法forName()和newInstance()的作用是什么。
答:使用Class的类方法
public static Class<?> forName(String className) throws ClassNotFoundException
就可以返回一个和参数className指定的类相关的Class对象。再让这个Class对象调用
public Constructor<?> getDeclaredConstructor() throws SecurityException
方法得到className类的无参数的构造方法(因此className类必须保证有无参数的构造方法)。
然后,Constructor<?>对象,调用newInstance()返回一个className类的对象。
8.正则表达式是什么,有什么作用。
答:正则表达式是一个String对象的字符序列,该字符序列中含有具有特殊意义字符,这些特殊字符称做正则表达式中的元字符。是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。可以使用正则表达式进行字符序列的替换和分解等操作。
组件与事件处理
1.java.awt包与javax.swing包的关系。
答:java.awt包是抽象窗口工具包,早期编写图形界面应用程序的包。
javax.swing包是为解决 AWT 存在的问题而新开发的图形界面包。Swing是对AWT的改良和扩展。javax.swing包中的JComponent类是java.awt包中Container类的直接子类,是java.awt包中Component类的一个间接子类。GUI变成主要使用Component类的一些重要子类。除了javax.swing包中的底层容器类以外,其余所有的Swing组件类都继承自JComponent类,如前所述,JComponent类是Container类的子类,因此,所有的Swing组件都可作为容器使用。
2.常用的底层容器有哪几个。
答:JFrame类的实例,即窗口;JDialog类的实例,即对话框。底层容器被默认添加到显示器的屏幕上,因此不允许将一个窗口添加到另一个容器中。
3.FlowLayout、BorderLayout、CardLayout、GridLayout布局各有什么特点。
答:FlowLayout布局:是JPanel型容器的默认布局。使用FlowLayout布局的容器用add()方法将组件顺序的添加到容器中,组建按添加的顺序从左向右排列,一行排满后转到下一行继续从左向右排列,每一行中的组件都居中排列,组件之间的默认水平和垂直间隙是5个像素。组件的大小为默认的最佳大小。
1)创建布局对象 : FlowLayout flow=new FlowLayout();
2)容器con使用布局对象: con.setLayout(flow);
3)con可以使用Container类提供的add方法将组件顺序地添加到容器中
FlowLayout布局对象调用相应的方法可以重新设置布局的对齐方式等.
如: public void setAlignment(int align)
BorderLayout布局:使用该布局的容器空间被分成东西南北中5个区域,中间区域最大,每加入一个组件都要指明把组件加到哪个区域中,添加到某个区域的组件将占据整个该区域,故每个区域只能放置一个组件,重复向一个区域添加组件会使先前添加进来的组件被替换。该布局最多容纳5个组件。
CardLayout布局:使用CardLayout的容器可容纳多个组件,这些组件被层叠的放入容器中,最先加入容器的是第一张(在最上面),依次向下排列。同一时刻容器只能从这些组件中选一个出来显示,这个被选中的组件将占据所有的容器空间。
GridLayout布局:GridLayout布局策略是把容器划分成若干行乘若干列的网格区域,组件就位于这些划分出来的小格中,每个网格都是相同大小并且强制组件与网格的大小相同。
4.事件处理模式的三个关键要素。
答:事件源、监视器、处理事件的接口。
事件源:能够产生事件的对象都可以称为事件源,如文本框、按钮、下拉列表等。事件源必须是一个对象,而且这个对象必须是java认为能够发生事件的对象。
监视器:需要一个事件对事件源进行监视,以便对发生的事件作出处理。事件源通过调用相应的方法将某个对象注册成自己的监视器。
处理时间的接口:监视器负责处理事件源发生的事件。监视器是一个对象,为了处理事件源发生的事件,监视器这个对象会自动调用接口中一个方法来处理事件。
为了让监视器这个对象能对事件源发生的事件进行处理,创建监视器对象的类必须声明实现相应的接口,即必须在类体中重写接口中的所有方法。
5.哪些组件能触发ActionEvent事件。
答:文本框、按纽、菜单项、密码框和单选按纽都可以触发ActionEvent事件,即都可以成为ActionEvent事件的事件源。能够触发ActionEvent事件的组件使用方法
addActionListener(ActionListener listener) 注册监视器,处理事件接口ActionListener接口中只有一个方法public void actionPerformed(ActionEvent e),事件源触发ActionEvent事件后,监视器将发现触发的ActionEvent事件,然后调用接口中的这个方法对发生的事件作出处理。ActionEvent类事先创建的事件对象就会传递给该方法的参数e。
ActionEvent类有如下常用方法:
public Object getSource() 可以获取发生ActionEvent事件的事件源对象的引用。
public String getActionCommand() 和该事件相关的一个“命令”字符串,对于文本框,当发生ActionEvent事件是,默认的“命令”字符串是文本框中的文本。
6.匿名类或窗口类或lambda表达式做监视器的优势。
答:匿名类的方便之处是匿名类的外嵌类的成员变量在匿名类中仍然有效,当发生事件时,监视器就比较容易操作事件源所在的外嵌类中的成员,不必把监视器所在窗口的引用传递给监视器。当事件的处理比较简单、系统也不复杂时,使用匿名类做监视器是一个不错的选择。
窗口类做监视器:能触发事件的组件经常位于窗口中,如果让组件所在的窗口做为监视器,则能让事件的处理比较方便,这是因为监视器可以方便的操作窗口中的其他成员。当事件的处理比较简单、系统也不复杂时,使用窗口类做监视器是一个不错的选择。
lambda表达式做监视器:如果处理事件的接口是函数接口,就可以把lambda表达式的值(方法的入口地址)传递给接口变量,即让lambda表达式做监视器,那么当事件源触发事件后,lambda表达式实现的接口方法就会被执行。lambda表达式在实现接口方法时可以使用外嵌类的成员变量,减少了代码量。
7.有模式和无模式对话框的区别。
答:对话框分为无模式和有模式两种。
有模式的对话框:当这个对话框处于激活状态时,只让程序响应对话框内部的事件,而且将堵塞其它线程的执行,用户不能再激活对话框所在程序中的其它窗口,直到该对话框消失不可见。
无模式对话框:当这个对话框处于激活状态时,能再激活其它窗口,也不堵塞其它线程的执行。
8.什么是MVC结构。
答:模型-视图-控制器(Model-View-Controller),简称为MVC。
MVC是一种先进的设计结构,其目的是以会话形式提供方便的GUI支持。
MVC是一种通过三个不同部分构造一个软件或组件的理想办法:
模型(model):用于存储数据的对象。
视图(view):为模型提供数据显示的对象。
控制器(controller):处理用户的交互操作,对于用户的操作作出响应,让模型和视图进行必要的交互,即通过视图修改、获取模型中的数据;当模型中的数据变化时,让视图更新显示。
9.适配器类的作用。
答:适配器可以代替接口来处理事件,当Java提供处理事件的接口中多于一个方法时,Java相应地就提供一个适配器类,比如WindowAdapter类。适配器已经实现了相应的接口,例如WindowAdapter类实现了WindowListener接口。因此,可以使用WindowAdapte的子类创建的对象做监视器,在子类中重写所需要的接口方法即可。
输入和输出流
1.数组流、数据流、对象流
答:
数组流:输入输出流的源和目的地除了可以是“文件”(硬盘)外,还可以是计算机内存。
数组流可以分为两类:字节数组流(ByteArrayInputStream和ByteArrayOutputStream)和字符数组流(CharArrayInputStream和CharArrayOutputStream)。它们分别以字节数组和字符数组作为流的源和目的地。
数据流:DataInputStream和DataOutputStream类创建的对象称为数据输入流和数据输出流。这两个流允许程序按着机器无关的风格读取java原始数据,也就是说,当读取一个数值时,不必再关心这个数值应当是多少字节。
对象流:用ObjectInputStream和ObjectOutputStream类(分别是InputStream和OutputStream类的子类)创建的对象称为对象输入(出)流。对象输出流使用writeObject(Object obj)方法可以将一个对象obj写入到一个文件中,对象输入流使用readObject()方法读取一个对象到程序中。ObjectInputStream的指向应当是一个输入流对象,ObjectOutputStream的指向应当是一个输出流对象。
2.什么是对象的串行化。
答:串行化的目的是为java的运行环境提供一组特性,其主要任务是写出对象实例变量的数值。对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。
我们把对象通过写出描述自己状态的数值来记录自己这个过程叫对象的串行化(Serialization)。把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性。在java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化。
串行化方法:
1)定义一个可串行化对象。
2)构造对象的输入/输出流
要串行化一个对象,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复。
3.简答RandomAccessFile类的特点。
答:RandomAccessFile类创建的流称作随机流,该类不是InputStream类、OutputStream类的子类。RandomAccessFile类创建的流的指向既可以作为流的源,也可以作为流的目的地,即准备对一个文件进行读写操作时,创建一个指向该文件的随机流即可,这样既可以从这个流中读取文件中的数据,也可以通过这个流写入数据到文件。
图形、图像与音频
1.Graphics2D类与Graphics类的关系。
答:Graphics 类是所有图形上下文的抽象基类,允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
Graphics2D 类扩展 Graphics 类,以提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。它是用于在 Java(tm) 平台上呈现二维形状、文本和图像的基础类。
Graphics2D 类是Graphics 类的子类,Graphics2D 类有强大的二维图像处理能力,它把直线、圆等作为一个对象来绘制,如果想用Graphics2D 类的“画笔”绘制一个图形形状,就必须先创建一个图形对象,Graphics2D 类的画笔使用draw()和fill()方法来绘制和填充一个图形。
2.绘制基本图形主要重写Component类的什么方法。
答:主要重写public void paint(Graphics g)方法。程序运行时,java运行环境会用Graphics2D 类将参数g实例化,这样对象g就可以在重写paint方法的组件上绘制图形、图像等。
3.旋转一个图形需要哪些步骤。
答:首先使用AffineTransform类创建一个对象,如trans;然后该对象trans调用rotate(double number,double x,double y)方法进行需要的变换,即先做好准备;最后把Graphics对象设置成有trans功能的画笔。
4.创建音频对象AudioClip和Applet类属于什么包。
答:AudioClip和Applet类属于java.applet包。
5.播放音频的步骤。
答:课本
1.创建File对象
File file=new File(“a.wav”);
2.得到Clip对象
Clip clip=RadioSystem.getClip();
3.clip打开音频流
AudioInputStream stream=AudioStream.getAudioInputStream(file);
clip.open(stream);
4.播放,循环与停止
clip.play() 开始播放,
clip.loop() 循环播放,
clip.stop() 停止播放。
5.关闭音频流
clip.close();
PPT
(1)创建File对象
File musicFile=new File("hello.wav");
(2)获取URI对象(URI类属于java.net包)
URI uri=musicFile.toURI();
(3)获取URL对象
URL url=uri.toURL();
(4)创建音频对象(AudioClip和Applet类属于java.applet包)
AudioClip clip=Applet.newAudioClip(url);
(5)播放,循环与停止
clip.play() 开始播放,
clip.loop() 循环播放,
clip.stop() 停止播放。
6.使用Graphics类绘制图像的步骤。
答:
(1)加载图像
组件调用getToolkit()方法可以返回这个对象的引用。Toolkit类的对象调用方法Image getImage(String fileNme)或Image getImage(File file),可以返回一个Image对象,该对象封装着参数file(或参数fileName)指定的图像文件。
(2)绘制图像
图像被加载后,即被封装到Image实例中后,就可以在paint()方法中绘制它。Graphics类提供了drawImage()方法用于绘制图像。
public boolean drawImage(Image img,int x,int y,ImageObserver observer);
参数img是被绘制的Image对象,x、y是要绘制指定图像的矩形的左上角所处的位置,observer是加载图像时的图像观察器。实现ImageObserver接口的类创建的对象都可以作为图像观察器,Java中的所有组件已经实现了该接口,因此任何一个组件都可以做图像观察器。
(窗口组件win)
Toolksit tool=win.getToolkit();
Image image=tool.getImage(“a.jpg”);