类型转换
1.向上转型(自动转型、隐式转型):
1.1 父类引用指向子类实例,小类型转为大类型。
1.2 可以调用子类重写父类的方法以及父类派生的方法,不可以调用子类自己的方法。
Animal dog = new Dog(); //Dog类是Animal类的子类
注意:
1.3 向上转型是安全的,以为任何子类都继承并接受父类的方法。
1.4. 父类中的静态方法A是不允许被子类重写的,当子类中也有定义同名的方法A时,那将算为是子类自己的静态方法A。子类向上转型后,调用静态方法A,执行的是父类的静态方法A。
2.向下转型(强制转型):
2.1 向下转型是与向上转型相对的概念,子类的引用指向父类对象
2.2 此处必须进行强转
2.3 可以调用子类特有的方法
2.4 必须满足转型条件才能强转(只能父子,不能兄弟)
Animal a = new Dog();
Dog d=(Dog)a;
3.instanceof运算符:
用来判断对象是否可以满足某个特定类型的实力特征。返回值为ture/false。一般用在if语句中。
if(two instanceof Cat) Cat temp = (Cat)two;
4.抽象类与抽象方法
4.1 基本概念:
父类是将子类所共同拥有的属性和方法进行抽取,这些属性和方法中,有的是已经明确实现了的,有的还无法确定,那么我们就可以将其定义成抽象,在后日子类进行重用,进行具体化。
抽象类是为了把相同的但不确定的东西的提取出来,为了以后的重用。定义成抽象类的目的,就是为了在子类中实现抽象类。
例如,定义了“动物”父类,其中“动物名称”和“动物年龄”属性已经明确了,但是“动物叫”的方法没有明确,此时就可以将“动物叫”定义为抽象方法。
public abstract class shape{
public abstract double area();
}
4.2 特点:
4.2.1 抽象方法不允许直接实例化,换句话说抽象类不能创建对象,它只能作为其他类的父类。但可以向上转型,指向子类实例。
4.2.2 抽象方法只有声明,不能有实现,也就是仅有方法头,而没有方法体和操作实现。
4.3 意义:
4.3.1 为其子类提供一个公共的类型(父类引用指向子类对象)
4.3.2 封装子类中重复的内容
4.3.3 将父类设计成抽象类后,既可借由父子关系限制子类的设计随意性,在一定程度上避免无意义父类的实例化。
4.4 注意:
4.4.1 含义抽象方法的类,只能被定义成抽象类
4.4.2 抽象类不一定含有抽象方法
4.4.3 在抽象类中的成员方法可以包括一般方法和抽象方法
4.4.4 抽象类不能被实例化,即使抽象类不包含抽象方法,这个抽象类也不能创建实例。,抽象类的构造方法主要是用于被其子类调用。
4.4.5 一个类继承抽象类后,必须实现其所有抽象方法,否者也得是抽象类,不同子类对付类的抽象方法可以有不同的实现。
4.4.6 即使父类是具体的,但其子类也可以是抽象的。例如Object是具体的,但可以创建抽象子类。
4.4.7 abstract方法不能用static和private修饰;对于类,不能同时使用final和abstract修饰,是因为final关键字会使类不能继承,而abstract修饰的类如果不可以继承将没有任何意义。两者放一起会起冲突。
5. 接口
5.1概念
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。
5.2 特点
1. 为了声明一个接口,我们使用interface这个关键字
2. 访问修饰符系统默认public,接口当中抽象方法可以不写abstract关键字
3. 当类实现接口时候,需要去实现接口里面的所有抽象方法,否则需要将该类设置为抽象类。
4. 一个接口能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。
5. default:默认方法,可以带方法体。可以通过实现类中重写,并可以通过接口的引用调用( JDK1.8后新增加)。
6. static:静态方法,可以带方法体。静态方法需要直接使用接口名调用,不可以在实现类中重写( JDK1.8后新增加)。
7. 接口中可以包含常量,默认带public static final
5.3 规则
1. 不能直接去实例化一个接口,因为接口中的方法都是抽象的,是没有方法体的。可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。
2. 一个类可以实现不止一个接口。
3. 一个接口可以继承于另一个接口,或者另一些接口,接口也可以继承,并且可以多继承。
4. 接口上实现要放在继承的后面。
5.4 重名
5.4.1 同名方法
当一个实现类调用两个接口,两个接口中有同名的默认方法,需要重写这个默认方法。
当一个实现类继承父类、调用了两个接口,他们仨都有一个同名方法,这时候会默认实现父类派生下来的方法。当然也可以重写父类派生的方法。
5.4.2. 同名常量
当实现类调用两个接口,接口中分别有两个同名常量时,需要明确访问的是哪一个接口中的常量。接口名+常量名进行调用。
当实现类继承一个类、调用两个接口,他们仨都有一个同名常量,需要在这个实现类中重新声明自定义这个同名的常量。
6. 内部类
6.1 概述
在Java中,可以将一个类定义在另一个类或者一个方法里面,这样的类称为内部类。与之对应,包含内部类的类叫外部类。通过内部类提供了更好的封装手段,可以将内部类的信息隐藏在外部类的内部,而不允许其他的类随意访问。
内部类的信息获取需要借助于外部类进行访问。
6.2 内部类的分类
1.成员内部类(普通内部类)
1. 内部类在外部使用时,无法直接实例化,需要借由类信息才能完成实例化
2. 内部类访问修饰符可以任意,但是访问范围会受到影响
3. 内部类可以直接访问外部类的成员,如果出现同名的属性,优先访问内部类中定义的。
4. 可以使用外部类.this.成员的方式,访问外部类中同名的信息。
5. 外部类访问内部类信息,需要通过内部类实例,无法直接访问。
6. 成员内部类编译后.class文件命名:外部类名称$内部类.class
2.静态内部类
1. 静态内部类中,只能直接访问外部类的静态成员(方法、变量),如果需要调用非静态的成员,可以通过实例对象调用
2. 静态内部类对象实例化时,可以不依赖于外部类对象
3. 可以通过外部类.内部类.静态成员的方式,访问内部类中的静态成员
4. 当内部类属性与外部类属性同名时,默认直接调用内部类中的成员;
如果需要访问外部类的中的静态属性,则可以通过 外部类.属性 的方式;
如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性 的方式;
3.方法内部类(局部内部类)
1. 定义在方法内部,作用范围也在方法内
2. 和方法内部成员使用规则一样,class面前不可以添加public、private、protected、static
3. 类中不能报包含静态成员
4. 类中可以包含final成员、abstract修饰的成员
4.匿名内部类
1. 匿名内部类没有类型名称、实例对象名称
2. 编译后的文件命名:外部类$数字.class
3. 无法使用public、private、protected、abstract、static修饰
4. 无法编写构造方法,可以添加构造代码块完成属性初始化操作
5. 不能出现静态成员
6. 匿名内部类可以实现接口也可以继承父类,但是不可兼得