黑马程序员面试题面向对象二(多态,抽象类abstract,接口Interface,内部类,异常Exception,包package,String类,StringBuffer)

时间:2021-06-06 00:47:22
 --------- android培训java培训、期待与您交流!---------

一.多态

1.多态的概念
(1) 多态:可以理解为事物存在的多种体现形态。
(2)多态的体现:
父类的引用指向了自己的子类对象。

方法的重载。

方法的覆盖。

(3)多态的前提:
<1>必须是类与类之间有关系,要么继承,要么实现。
<2>通常还有一个前提:存在覆盖。

(4)多态的好处:
多态的出现大提高了程序的扩展性。

(5)多态的弊端:
只能使用父类的引用访问父类中的成员。

2.转型(引用类型强制转换)
(1)类型提升--->向上转型  //  Animal a = new Cat();
(2)转成子类型--->向下转型 //  Cat c = (Cat)a;
3.多态中成员的特点
(1)多态中成员函数的特点:
<1>在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过。如果没有,编译失败。
<2>在运行时期:参阅对象所属的类中是否有调用的方法。
<3>总结:成员函数在多态调用时,编译看左边,运行看右边。
(2)多态中成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类).
(3)多态中,静态成员函数的特点:
无论编译和运行,都参考左边。

二.抽象类

1.概述
(1)当多个类中出现相同功能,但是功能主体不同,这时可以进进向上抽取。
(2)这时只抽取功能定义,而不抽取功能主体。
(3)抽象就是笼统的,不具体的,看不懂的。

2.抽象类的特点:
(1)抽象方法一定在抽象类中。
(2)抽象方法和抽象类都必须被abstract关键字修饰。
(3)抽象类不可以用new创建对象,因为调用抽象方法没意义。
(4)抽象类中的抽象方法要被使用,必须由子类复写齐所有的抽象方法后,建立子类对象调用。
(5)如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
(6)抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

三.接口

1.接口:
初期理解,可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以
通过接口的形式来表示。
2.区别:
class用于定义类。
interface用于定义接口。
3.接口的格式:interface{}
4.接口定义的格式特点:
(1)接口中常见定义:常量,抽象方法。
(2)接口中的成员都有固定修饰符。
常量:public static final
方法:public abstract
5.注意:
(1)接口中的成员都是public的。
(2)接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法
全部覆盖后,子类才可以实例化,否则子类是一个抽象类。
6.接口的特点:

(1)接口可以被多实现,也可以多继承。
(2)接口是对外暴露的规则。
(3)接口是程序的功能扩展。
(4)接口降低了偶合性
(5)类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
(6)接口与接口之间可以有继承关系。
(7)基本功能定义在类中,扩展功能定义在接口中。

四.内部类

1.内部类
(1)将一个类定义在另一个类的里面,对里面那个类就称为内部类,或叫内置类,嵌套类。
(2)访问特点:
<1>内部类可以直接访问外部类中的成员,包括私有成员。
<2>外部类要访问内部类中的成员,必须要建立内部类的对象。

3)注意:
<1>内部类之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用。
格式为:外部类名.this

<2>内部类可以被私有封装。
<3>内部类可以被static修饰。

2.静态内部类
(1)访问格式:
<1>当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。
格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象
如: Outer.Inner in = new Outer().new Inner();
<2>当内部类在成员位置上,就可以被成员修饰符所修饰。
比如:private:将内部类在外部类中进行封装。
static :内部类就具备static特性

a.当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
b.在外部其他类中,如何直接访问static内部类的静态成员呢?
new Outer.Inner().function();
c.在外部其他静态类中,如何直接访问static 内部类的静态成员呢?
Outer.Inner.function();

(2)注意:
<1>当内部类中定义了静态成员,该内部类必须是static的。
<2>当外部类中的静态方法访问内部类时,内部类也必须是静态的。

3.内部类的定义原则:

当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容。

4.匿名内部类:

要点: 
(1)内部类只有定义在成员位置上时,才能被private和static所修饰,一般内部类是不会被public所修饰的。
(2)内部类可以被写在任意位置上,成员也可以。局部也可以。
(3)非静态,没对象不运行
(4)从内部类中访问局部变量,需要被声明为最终类型(加final).
(5)内部类定义在局部时:
<1>不可以被成员修饰符修饰。
<2>可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,
只能访问被final修饰的局部变量。

注意:
(1)匿名内部类其实就是内部类的简写格式。
(2)定义匿名内部类的前提:内部类必须是继承一个类或者接口。
(3)匿名内部类的格式:new 父类或接口(){定义子类的内容}
(4)其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为带内容的对象。
(5)匿名内部类中定义的方法不要超过3个,最好是2个或者1个。
(6)定义匿名内部类,就是为了简化书写,覆盖方法。

五.Object类

1.Object类
(1)Object:是所有对象的直接或者间接父类,是一个超类,该类中定义的肯定是所有对象都具备的功能。
(2)Object类中已经提供了对对象是否相同的比较方法,如果自定义类中也有比较相同的功能,没必要
重新定义,只要沿袭父类中的功能,建立自己特有的比较内容即可,这就是覆盖。
(3)java认为所有对象都具备比较性,该方法equals定义在Object中。
2.Object中方法:
(1)toString():返回该对象的字符串表示,所有对象都可以变成字符串打印。
(2)hashCode():返回该对象的哈希码值。
(3)getClass():返回此Object的运行时类。

(4)wait();

(5)notify();

(6)notifyAll();

六.final关键字

final:意为“最终”,是一个修饰符。
(1)可以修饰类,函数,变量。
(2)被final修饰的类,不可以被继承。
(3)被final修饰的方法不可以被复写。如:final void show(){}//最终方法
(4)被final修饰的变量是一个常量。如:final int x=3;
(5)内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。

七. 异常类

1 异常概述: 异常是对问题的描述,将问题封闭成对象  以便抛出和处理。

2 异常体系:

Throwable

         |----------Error

         |----------Exception

         |----------RuntimeException

3 异常体系的特点:

 异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字所操作。

4 throw 和Throws

throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可抛出多个异常 用逗号隔开。

5 当函数内有throw抛出异常对象,并未进行try处理 必须要在函数上声明,否则编译失败,

注意:RuntimeException及它的子类除外,也就是说,函数内如果抛出了RuntimeException异常,函数上可以不用声明,

如果函数声明了异常,调用者需要进行处理 处理方法可以throws也可以try.

6异常分为两种

(1)编译时被检测异常Exception,如果没有处理,那么编译失败,该异常可以被标识,代表可以被处理。

(2)运行时异常RuntimeException 不需要处理,该异常发生,让程序停止,需要对代码进行修正。

7,异常处理语句:

try{被检测的代码}catch{处理的代码}finally{一定会执行的语句} 

 finally通常是关闭资源,释放资源使用,只有当执行到System.exit(0)的时候 finally中的代码不会被执行。遇到return也要执行。

8自定义异常

(1)定义类继承Exception或RunTimeException

<1>为了让该自定义类具备可抛性。
<2>让该类具备操作异常的共性方法。

(2)当要定义自定义异常的信息时,可以使用父类已经定义好的功能,将异常信息传递给父类的构造函数。
class MyException extends Exception
{
       MyException(String message)
       {
         super(message);
       }
}

自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。

10异常的好处:
(1)将问题进行封装。
(2)将正常流程代码和问题处理代码相分离,方便于阅读。

11.异常处理原则:
(1)处理方式有两种:try或throws.
(2)调用到抛出异常的功能时,抛出几个就处理几个,一个try可对应多个catch.
(3)多个catch时,父类的catch放到最下面,否则子类的catch执行不到。
(4)catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句,也不要不写。
(5)当捕捉到的异常,本功能处理不了时,可以继续在catch中抛出。

12.异常的注意事项:
在子父类覆盖时:
(1)子类抛出的异常必须是父类的异常的子类或子集。
(2)如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try处理不能抛出。


八. 包

1.包:
包也是一种封装形式,可对类文件进行分类管理,给类提供多层命名空间。
写在程序文件的第一行,类名的全称是:包名.类名

2.包的好处:
包的出现可以让类文件和java的源文件相分离,可以很方便地只将类文件提供给别人使用。

3 包与包之间的访问:

(1)一个包中的类要被访问,必须要有足够大的权限,所以被访问的类要被public修饰。
(2)类公有后,被访问的成员也要公有才可以被访问。
(3)包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
(4)不同包中的子类还可直接访问父类中被protected权限修饰的成员。
(5)包与包之间可以使用的权限只有两种:public,protected.

4.java中四种权限
                           public     protected    default       private
同一个类中:     OK             OK             OK         OK

同一个包中:    OK             OK            OK

不同包子类:    OK             OK

不同包中:        OK

5.import
(1)为了简化类名的书写,使用一个关键字import,import导入的是包中的类。
(2)import packb.*;为导入包中所有的类,尽量不要写通配符*,需要用到哪个类就导入哪个类,
都导进来比较占内存。
(3)建立定义包名不要重复,可以使用url来完成定义,因为url是唯一的。
如:package cn.itcast

(4)包和子包中有重名类时,创建对象必须加包名。
如:packb包和子包haha中都有DemoC,创建packb包中DemoC对象代码为:
packb.DemoC c = new packb.DemoC();

6.jar包
(1)java中的jar包是通过工具jar.exe完成的。
(2)java的压缩包方便项目的携带,方便于使用,只要在classpath设置jar路径即可。
(3)数据库驱动,SSH框架等都是以jar包体现的。

 九. String类

1.String概述:

 (1)public final class String   此类不能有子类,也就是操作字符串的功能不可以被复写。
 (2)String类代表字符串,java程序中所有的字符串字面值(如:"abc")都作为此类的实例实现。
 (3)字符串是常量,它们的值在创建后不能更改。
2.s1和s2的区别:
String s1="abc";
String s2=new String("abc");

s1==s2   flase;     ==比较的是两个对象的引用地址  这是两个不同的对象 所以false;

s1.equals(s2)  true   equals本身也是比较两个对象的引用地址

但是在这里被String字符串复写了,比较对象的内容是否相同。
s1在内存中有一个对象。
s2在内存中有两个对象。

3.String 类在内存中的原理分析:
String类在内存中有一个常量池,也就是一个数组,将字符按指定顺序存入数组来组成字符串。

4 String常见方法:

获取:

(1)获取长度:int length()
(2)根据位置获取字符:char charAt(int index)
(3)根据字符获取位置:
int indexOf(int ch):返回ch在字符串中第一次出现的位置。
int indexOf(int ch,int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。
int indexOf(String str):返回str在字符串中第一次出现的位置。
int indexOf(String str,int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置。
int lastIndexOf(int ch):返回字符在字符串中最后一次出现的索引位置。

判断:
(1)字符串中是否包含某一个子串:boolean contains(str)
(2)字符串中是否有内容:boolean isEmpty()
(3)字符串是否是以指定内容开头:boolean startsWith(str)
(4)字符串是否是以指定内容结尾:boolean endsWith(str)
(5)判断字符串内容是否相同(复写Object类中的equals方法):boolean equals(str)
(6)判断内容是否相同并忽略大小写:boolean equalsIgnoreCase()

转换:

(1)将字符数组转成字符串:
构造函数:
String(char[])
String(char[],offset,count)//将字符数组中的一部分转成字符串。
静态方法:
static String copyValueOf(char[])
static String copyValueOf(char[] data,int offset,int count)
static String valueOf(char[])
(2)将字符串转成字符数组:char[] toCharArray()
(3)将字节数组转成字符串:
String(byte[])
String(byte[],offset,count)
(4)将字符串转成字节数组:byte[] getBytes()
(5)将基本数据类型转成字符串:
static String valueOf(int)
static String valueOf(double)
注:3+"" <==> String.valueOf(3);
字符串和字节数组在转换过程中,是可以指定编码表的。
替换和切割:
(1)String replace(oldChar,newChar);
(2)String replace(charSequence target,charSequence replacem):替换字符串
(3)切割:String[] split(regex)
(4)获取子串:
String substring(begin)
String substring(begin,end)
比较和去除空格:
(1)将字符串转成大写或小写:
String toUpperCase();
String toLowerCase();
(2)将字符串两端的多个空格去除:String trim();
(3)对两个字符串进行自然顺序的比较:int compareTo(String);

十.StringBuffer        

1.关于StringBuffer
(1)字符串的组成原理就是通过该类实现的。
(2)StringBuffer可以对字符串内容进行增删。
(3)StringBuffer是一个容器。
(4)很多方法与String相同。
(5)StringBuffer是可变长度的。

2.public final class StringBuffer
StringBuffer不能被继承,它是字符串的缓冲区。
缓冲区特点:
长度可变。
可操作多个数据类型。
最终会通过toString方法变成字符串.才可以操作。

3.StringBuffer中方法:
(1)存储:
StringBuffer append():将指定数据作为参数添加到已有数据结尾处。
StringBuffer insert(index,data):可将数据插入到指定index位置。
(2)删除:
StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end.
StringBuffer deleteCharAt(index):删除指定位置的字符。
(3)获取:
char charAt(int index);
int indexOf(String str);
int lastIndexOf(String str);
int length();
String substring(int start,int end);
(4)修改:
StringBuffer replace(start,end,String str);
void setCharAt(int index,char ch);
(5)反转:
StringBuffer reverse();
(6)将缓冲区中指定数据存储到指定字符数组中:
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin);

4StringBuilder和StringBuffer区别                                    

(1)StringBuffer是线程同步,多线程中使用。
StringBuilder是线程不同步,单线程使用。

        (2)StringBuilder:一般开发中用StringBuilder 比StringBuffer更高效。


十一. 基本数据类型包装类

1.基本数据类型对象包装类:
byte Byte
short Short
int Integer
long Long
boolean Boolean
float Float
double Double
char Character
2.基本数据类型对象包装类的最常见作用:
---就是用于基本数据类型和字符串类型之间做转换
(1)基本数据类型转成字符串:
基本数据类型 + "";
基本数据类型.toString(基本数据类型值);如:Integer.toString(34)
(2)字符串转成基本数据类型:
xxx a = XXX.parseXXX(String str);//静态方法
如:int a = Integer.parseInt("123");
double b = Double.parseDouble("12.23");
boolean b = Boolean.parseBoolean("true");
3.十进制---->其他进制
toBinaryString();//2
toHexString();//16
toOctalString();//8
4.其他进制--->十进制
parseInt(string,radix);如:parseInt("110",10);
5.基本数据类型对象包装类新特性
Integer x=4;//自动装箱,隐式完成了new Integer(4)动作。
x=x+2;//x进行自动拆箱,变成了int类型,和2进行加法运算,再将和进行装箱赋给x;

注:x的拆箱原理:x.intValue();
Integer x=null;//NullPointException空指针异常