java面试第五天

时间:2024-01-11 21:19:50

修饰符abstract:抽象的,定义框架不去实现,可以修饰类和方法

abstract修饰类:

会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型

抽象类就相当于一个类的半成品,需要子类继承并覆盖其中的抽象方法,这时子类才又创建实例的能力,如果子类没有实现父类的抽象方法,那么子类也要为抽象类。

abstract修饰方法:

会使这个方法变成抽象方法,也就是只有声明而没有实现,实现部分以";"代替,需要子类继承实现。

抽象方法代表了某种标准,定义标准,定义功能,在子类中去实现功能(子类继承了父类并需要给出从父类继承的抽象方法的实现)。

方法一时间想不到怎么被实现,或有意要子类去实现而定义某种标准,这个方法可以被定义为抽象。

注意:

有抽象方法的类一定是抽象类。但是抽象类中不一定都是抽象方法,也可以全是具体方法。

接口(interface):

接口的定义:接口从本质上说是一种特殊的抽象类。

关键字interface。

在接口中,所有的方法为公开、抽象的方法:public abstract

在接口中,所有的属性都是公开、静态的常量:public static final

接口与接口之间可以多继承,用extends,多个之间用逗号隔开。

接口中没有构造方法,不能用“new 接口名”来实例化一个接口,但可以声明一个接口。

接口的实现:

关键字implements

一个类实现一个接口必须实现接口中所有的方法,否则其为抽象类,并且在实现类中的方法要加上public(不能省略)。

类中的默认修饰符:default。

接口中的默认修饰符:public。

一个类除了继承另一个类外(只能继承一个类),还可以实现多个接口(接口之间用逗号分隔)。

接口的作用:

间接实现多继承:用接口来实现多继承并不会增加类关系的复杂度。因为接口不是类,与类不在一个层次上,是在类的基础上进行再次抽象。

接口可以抽象出次要类型,分出主、次关系类型,符合看世界的一般方法。

接口隔离,与封装性有关。一个对象都有多个方面,可以只展示其中几个方面,其他的都隐藏。因此可以看为“更高层次的封装”,把 一个大接口做成若干个小接口。

通过接口制定标准(最重要的作用)----接口的作用,协议的制定。

接口:制定标准。

接口的调用者:使用标准。

接口的实现类:实现标准。

解耦合作用:把使用标准和实现标准分开,使得标准的制定者和实现者解除偶合关系,具有极强的可移植性

例:sun公司提供一套访问数据库的接口(标准),java程序员访问数据库时针对数据库接口编程。接口由各个数据库厂商负责实现。

接口编程的原则

尽量针对接口编程(能用接口就尽量用接口)

接口隔离原则(用若干个小接口取代一个大接口)

注意:

接口中没有构造器,也没有main方法

封装类:

Java为每一个简单数据类型提供了一个封装类。

除int和char,其余类型首字母大写即成封装类。

int                Integer

char             Character

最常用的两个封装类Integer和Double

jdk1.4之前基本类型和封装类的转化是需要构造器去转化的,到了jdk1.5是自动进行转化的

int、Integer和String之间的转化(最常用的)

int i=1;

Integer in = new Integer(i);                                //int --> Integer

int  i = in.intValue();                                            //Integer --> int

String  str = String.valueOf(i);                           //Int --> String

int  ii = Integer.parseInt(str);                           //String --> int

String  s = in.toString();                                     //Integer --> String

Integer inte = Integer.valueOf(str);                   //String --> Integer

Object类

hashCode():

返回该对象的哈希码值

hashCode 的常规协定是:

在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。

如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果,反之不一定成立,例如针对hashmap,hashtable,与arraylist是不一样的。

toString():

返回该对象的字符串表示。

通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂。建议所有子类都重写此方法。

equals()

指示某个其他对象是否与此对象“相等”。

equals 方法在非空对象引用上实现相等关系:

自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。

对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。

传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。

一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y)始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。对于任何非空引用值 x,x.equals(null) 都应返回 false。

注意:

当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

String、StringBuffer和StringBulder

String: 不可改变的Unicode字符序列

池化思想,把需要共享的数据放在池中,用一个存储区域来存放一些公用资源以减少存储空间的开销。

在String类中,以字面值创建时,会到Java方法空间的串池中去查找,如果没有则会在串池里创建一个字符串对象,并返回其地址赋给对象变量,如果有就返回串池中字符串的地址,并把这个地址赋给对象变量。

如果是new,则会在堆空间中创建String类的对象,不会有上述的过程

如:

String s1 = "abc";            //新创建,字符串常量池中没有该串,则会在池中创建一个串"abc"

String s2 = "abc";            //串池中已经存在"abc",则s2会去指向"abc"而不会去创建一个新的

String s3 = new String("abc");           //直接在堆中去开辟一个新的空间,而不会去池中查找

类中的具体方法查看下Api文档。

调用任何String中的方法,不会改变String自身,除非重新赋值。

StringBuffer: 可改变的Unicode字符序列

允许并发操作,是线程安全的

String类在进行字符串连接时会显得效率很低,就是因为它所产生的对象的属性是不能够修改的,当连接字符串时也就只能创建新的对象。

对于很多字符串连接时,应当使用StringBuffer类,使用这个类的对象来进行字符串连接时就不会有多余的中间对象生成,从而优化了效率。

例:对于字符串连接String str = "A" + "B" + "C" + "D";

产生:"AB"、"ABC"、"ABCD"

在串池中产生的"AB"、"ABC"明显是多余对象,浪费空间。

解决方案:

String s = null;

StringBuffer sb = new StringBuffer("A");

sb.append("B");

sb.append("C");

sb.append("D");

s = sb.toString();

StringBulder: 可改变的Unicode字符序列

操作同StringBuffer,只是不支持并发操作,非线程安全的