JAVA基础-多态、抽象类、instanceof关键字、代码块
一、多态
1.什么是多态
概念:一个对象,在不同的条件下具有多种表现形态就叫多态。
在生活中,每个个事物都有不同的表现形式。例如:对老板而言我是工人,对于母亲而言我是儿子,对于儿子而言我是父亲。
在程序中,多态就是父类引用指向子类对象。
/**
定义了一个Animal类
*/
public class Animal {
}
/**
定义了一个Cat类继承了Animal类
*/
public class Cat extends Animal {
}
public class AnimalDemo {
public static void main(String[] args) {
// 父类的引用指向指向子类的对象就是多态
Animal a = new Cat();
}
}
2.多态的前提
1.继承;
2.方法重写
3.多态时的运行状态
Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由 实际赋给该变量的对象决定。
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
//编译时类型 | 运行时类型
}
}
简单的说:等号左边的就是编译时类型,右边的就是运行时类型。
3.1.类成员多态下的运行状态分析
类的成员:成员变量、方法、静态成员变量、静态方法;目前我们只讨论以上几个。
成员变量
public class Animal {
public int num = 5;
}
public class Cat extends Animal {
public int num = 6;
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
System.out.print(a.num)//5
}
}
结果:5
从以上代码以及所展示的结果可以看出对于成员变量在多态下,只与编译时类型有关。
方法
public class Animal {
public void show(){
System.out.println("Animal");
}
}
public class Cat extends Animal {
public void show() {
System.out.println("Cat");
}
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.show();//Cat
}
}
结果:Cat
从以上代码可以看出,对于方法而言在多态下,编译时使用的编译时类型,运行时使用的是运行时类型。编译看左边(Animal a)是否存在show()方法,如果存在则编译通过,如果不存在则编译不能通过;运行看左边(new Cat())是否重写了父类的show()方法,如果重写了则执行的是子类重写过后的方法,如果没有重写则执行的是父类的方法。
静态成员变量
public class Animal {
public static int num = 5;
}
public class Cat extends Animal {
public static int num = 6;
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
System.out.print(a.num);//5
}
}
结果:
从以上代码以及所展示的结果可以看出对于静态成员变量在多态下,只与编译时类型有关。
静态成员方法
public class Animal {
public static void show(){
System.out.println("Animal");
}
}
public class Cat extends Animal {
public static void show() {
System.out.println("Cat");
}
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.show();//Cat
}
}
结果:Animal
从以上代码以及所展示的结果可以看出对于静态成员方法在多态下,只与编译时类型有关。
总结:在多态下,除成员方法编译时看编译时类型,运行时看运行时类型外,其它的都只与编译时类型有关。感兴趣的同学可以通过分析类继承–方法重写–堆内存得出这个结论。
二、类型转换
在Java中类型转换分为两种:
1.向上类型转换:一般用于小的类型向大的类型转换,自动完成。
2.向下类型转换:一般用于大的类型向小的类型转换,需要强制转换;
友情提示:这里的类型转换与基本数据类型的转换基本相似,基本数据类型向下类型转换时需要注意的是:精度丢失;那么引用数据类型的向下类型转换需要注意的是:类型转换异常。我们可以在编写转换的过程中使用A(子类)是B(父类)的形式来判断。
三、instanceof关键字
instanceof是一个运算符
此运算符的使用格式为:对象 instanceof 类型
此运算符运行的结果为一个布尔值。
作用:用于判断两个对象是否为同一类型。
案例:
public class A{}
public class B extends A{}
public class C extends B{}
public class ATest{
public static void main(String[] args){
B b = new B();
System.out.println(b instanceof A);//true
}
}
四、代码块
Java中主要有三种形式的代码块
1.静态代码块
案例:
public Demo{
static{
}
}
1)写在类中
2)遵循static关键字规则:静态代码块中只能调用静态的成员变量和方法
3)不能被调用,只能在类加载的时候执行
4)一般用于对静态成员变量初始化
2.构造代码块
案例:
public Demo{
{
}
}
1)写在类中
2)不能被调用,只能在类实例化的之前执行
3)一般用于对成员变量初始化
3.局部代码块
案例:
public Demo{
public void test(){
{
}
}
}
很少被使用,知道有就可以了。
五、抽象类
1.为什么要有抽象类
当子类继承父类后,在多态的条件下,子类重写父类的方法后,我们得到的结果就是子类重写后的结果,那么父类的方法实现对我们来说就失去了意义。我们就可以不再为父类中的方法构写方法体了,只需要声明这个方法就可以了。这时就需要使用到抽象方法了。
public abstract class Animal{ abstract void eat();}
1.抽象方法
当一个方法只有声明没有实现,那么该方法必须要使用abstract关键字修饰,而被abstract关键字修饰的方法就叫抽象方法。
public abstract class Animal{ abstract void eat();//抽象方法}
2.抽象类
如果一个类中有抽象方法,那么此类也必须被abstract修饰,而被abstract修饰的类就叫抽象类。
3.抽象类特点
1)需要被abstract关键字修饰;
2)抽象类中可以有抽象方法,也可以没有抽象方法;
3)抽象类不能直接实例化
4)抽象要被继承才会有意义
5)子类继承了抽象的父类后,如果没有重写父类的所有抽象方法,那么子类也必须是抽象类;
4.abstract使用注意事项
-
abstract关键字不能与final关键字一起使用;
- 被abstract修饰的类必须有子类;而被final修饰的类不能有子类;
2. 被abstract修饰的方法必须重写;而被final修饰的方法不能被重写;
- 被abstract修饰的类必须有子类;而被final修饰的类不能有子类;
-
abstract关键字不能修饰成员变量
案例:
private abstract String name; // 报错:Illegal modifier for the field name; only public,
-
abstract关键字不能与static关键字一起使用;
- static修饰的方法又可以称为类方法,是和类加载的时候一起加载的;而abstract时需要被继承的。