多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作
Parent p = new Child();
对于多态,可以总结以下几点:
一、使用父类类型的引用指向子类的对象;
二、该引用只能调用父类中定义的方法和变量;
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用);
2、java.lang.Object类是所有类的根父类,如何理解这句话?
(1)所有类型都最终会调用Object的无参构造
(2)java.lang.Object类中所有的方法在子类中都有,包括数组对象
(3)java.lang.Object类型的变量与所有类型的实例都可以构成多态引用
默认调用
toString()方法默认返回的是:类名 @ 哈希码的十六进制值 也就是地址值
equals(Object obj) 一般用于对象之间判断 如果不重写的话结果应该是和==相同的,比较的就是地址值、但是equals可以被重写,你可以定义这个规则,在String中 已经被重写过了,比较的就是字符串是否相同
hashCode():理想状态下,每一个对象都有一个唯一的hashcode码,但是现实中,只要保证
“相等的”两个对象的hashcode值必须相等,如果两个对象的hashcode值不相等,意味着这两个对象肯定是不相等,
如果hashcode值相等,这两个对象可能相等可能不相等,还需要依据equals方法进行判断
hashCode 是散列值,并不能表现其唯一性,但是有离散性,其意义在于类似于进行hashMap等操作时,加快对象比较的速度,进而加快对象搜索的速度。
4、请阐述Java的类型转换
(1)基本数据类型:8种
自动类型转换:从存储范围小的到存储范围大,自动完成
byte,short,char --> int --> long -->float -->double
byte,short,char之间不进行转换,如果有混合运算,直接升级到int或以上
强制类型转换:从存储范围大的到存储范围小,需要使用强制类型转换符()
强制类型转换有风险,可能溢出或损失精度
boolean与他们都不进行转换
(2)引用数据类型:
类、接口、数组
向上转型:子类-->父类,自动完成,构成多态引用
向下转型:父类-->子类,需要强制转换符
如果想要转换成功,要求父类的变量本身就是指向该子类的对象,否则会报ClassCastException
为了避免这个异常,可以在类型转换之前做判断,使用instanceof
5、多态的两个应用:
(1)多态数组 也就是在数组中的数据存放的是父类类型
(2)多态参数 参数也是写的父类类型
内部类Inner Class
1、为什么要有内部类
(1)当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类
(2)内部类可以访问外部类的所有的成员,包括私有的
源代码示例:JRE核心类库集合的迭代器大量使用内部类
2、内部类的分类
静态内部类
非静态内部类:
成员内部类
局部内部类
匿名内部类
3、成员内部类
(1)如何声明成员内部类
声明的位置:在类中方法外
格式如下:
class 外部类{
class 成员内部类{
}
}
(2)如何使用成员内部类
-
在外部类中使用成员内部类:
-
在外部类的静态成员中不能使用内部类
-
在外部类的非静态成员中,直接创建内部类的对象来访问内部类的属性与方法。此时把它当做一个普通的类即可
-
-
在外部类的外面使用成员内部类:
需要外部类的对象才能创建成员内部类的对象
package com.innerclass.member;
public class TestMemberClass {
public static void main(String[] args) {
Outer out = new Outer();
out.outerMethod();
Outer.Inner oi = out.new Inner();
oi.innerMethod();
Outer.Inner obj = out.getInner();
obj.innerMethod();
}
}
class Outer{
private int value = 5;
public static void outerStaticMethod(){
/*Inner in = new Inner();
in.innerMethod();*/
}
public void outerMethod(){
System.out.println("外部类的方法");
/*Inner in = new Inner();
in.innerMethod();*/
}
class Inner{
public void innerMethod(){
System.out.println("内部类的方法");
System.out.println("内部类的方法访问外部类的私有成员:"+value);
}
}
//通过外部类的某个方法返回内部类的对象
public Inner getInner(){
return new Inner();
}
}
(3)成员内部类的特点
-
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。例如:Outer$Inner.class
-
成员内部类可以使用修饰符public,protected,default,private
-
成员内部类还可以使用final和abstract修饰
-
成员内部类中不可以包含静态成员
-
成员内部类可以直接使用外部类的所有成员,包括私有的
注意
InnerClass in = new OutClass().new InnerClass();//定义内部类成员变量
和
InnerClass in = new OutClass.new InnerClass();
的区别 第二种是表示 创建的是OutClass中的静态的内部类
class Outer{
public static void outerStaticMethod(){
static class StaticInnerClass{
public static void innerStaticMethod(){
System.out.println("内部类的静态方法");
}
}
(3)如何使用静态内部类
-
在外部类中使用静态内部类:就和使用其他普通类一样
-
在外部类的静态成员中
-
在外部类的非静态成员中
-
-
在外部类的外面使用成员内部类:
使用静态内部类的静态成员:外部类名.静态内部类名.静态内部类的静态成员
使用静态内部类的非静态成员:外部类名.静态内部类名 obj = new 外部类名.静态内部类名();
obj.静态内部类的非静态成员
补充说明:静态内部类中有与外部类重名的属性时,如果要表示是外部类的属性,那么用外部类名.属性
4)静态内部类的特点
-
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。例如:Outer$Inner.class
-
静态内部类可以使用修饰符public,protected,default,private
-
静态内部类还可以使用final和abstract修饰
-
静态内部类中可以包含静态成员
静态内部类可以直接使用外部类的静态成员,包括私有的。但不能使用非静态成员。
局部内部类 使用的意义就是缩小类的使用范围 不能被外部的类使用
(1)如何声明局部内部类
声明的位置:在外部类的方法或代码块中
格式如下:
class 外部类{
方法(){
class 局部内部类{
}
}
{
class 局部内部类{
}
}
}
(2)如何使用局部内部类
-
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
-
但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型。
package com.innerclass.local;
public class TestLocalInnerClass {
public static void main(String[] args) {
Outer out = new Outer();
Object obj = out.outerMethod();
System.out.println(obj);
}
}
class Outer{
int value = 5;
public Object outerMethod(){
final int localValue = 10;
class LocalInnerClass{
public void innerMethod(){
System.out.println("局部内部类的方法");
System.out.println("局部内部类的方法可以使用外部类的成员:"+value);
System.out.println("局部内部类的方法可以使用外部类的局部变量:"+localValue);
}
}
//先声明后使用
LocalInnerClass li = new LocalInnerClass();
li.innerMethod();
return li;
}
}
(3)局部内部类的特点
-
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。
-
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
-
局部内部类可以使用外部类的成员,包括私有的
-
局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
-
局部内部类和局部变量地位类似,不能使用public,protected,default,private
-
局部内部类不能使用static修饰,因此也不能包含静态成员
枚举的使用
使用 enum 定义的枚举类默认继承了 java.lang.Enum类。因此不能再继承其他类。
-
枚举类的所有构造器只能使用 private 访问控制符
-
枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾),必须在枚举类的第一行声明枚举类对象。列出的实例系统会自动添加 public static final 修饰
-
JDK 1.5 之后可以在 switch 表达式中使用Enum定义的枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字
package com.enumtype.after15;
public class TestEnumType {
public static void main(String[] args) {
Season s = Season.SPRING;
switch(s){
case SPRING:
System.out.println("春暖花开");break;
case SUMMER:
System.out.println("夏日炎炎");break;
case AUTUMN:
System.out.println("秋高气爽");break;
case WINTER:
System.out.println("白雪皑皑");break;
}
}
}
enum Season{
SPRING,SUMMER,AUTUMN,WINTER;
}
public class EnumTest {
public static void main(String[] args) {
System.out.print(A.Monday); //Monday
System.out.print(A.Friday.getName());//美女
}
enum A {
Monday, Sunday, Wendsday, Friday("美女");
private String name;
private A(){
}
private A(String a){
this.name =a;
}
private void setName(String name ){
this.name=name;
}
private String getName(){
return this.name;
}
}
}
注解Annotation