- 需要存在方法重写
- 优势
-
在多态形式下,右边对象可以实现组件化切换,业务功能也随之改变,便于扩展和维护。可以实现类与类之间的解耦
-
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,可以传入一切子类对象进行方法的调用,更能体现出多态的扩展性与便利
- 劣势
-
多态形式下,不能直接调用子类特有的功能。(编译看左边!!)
-
因为父类中没有子类独有的功能,所以代码在编译阶段就直接报错了
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
我们先来看基本数据类型的转换:
-
小范围类型的变量或者值可以直接赋值给大范围类型的变量
-
大范围类型的变量或者值必须强制类型转换给小范围类型的变量
引用数据类型转换的思想是一样的:
-
父类类型的范围 > 子类类型的范围
-
Animal > Cat
-
子类类型的对象或者变量可以自动类型转换赋值给父类类型的变量
Animal a = new Cat();
-
父类类型的变量或者对象必须强制类型转换成子类类型的变量,否则报错!
-
强制类型转换的格式:
-
类型 变量名称 = (类型)(对象或者变量)
Animal a = new Wolf();
// 把动物类型的变量a转换为真实的狼类型
Wolf w = (Wolf) a;
-
有继承/实现关系的两个类型就可以进行强制类型转换,编译阶段一定不报错
-
但是在运行阶段可能出现:类型转换异常
ClassCastException
-
建议在进行强制类型转换之前先判断变量的真实类型,再强制类型转换(
instanceof
)
Animal a1 = new Cat();
// Wolf w1 = (Wolf) a1; //编译阶段没有报错 在运行阶段可能出现类型转换异常
if(a1 instanceof Cat){
// 如果a1 属于猫类型,执行抓老鼠
Cat c1 = (Cat) a1;
c1.catchMouse();
}else if(a1 instanceof Wolf){
// 如果a1 属于狼类型,执行抓羊
Wolf w1 =(Wolf) a1;
w1.catchSheep();
}
- 什么是内部类?
答:定义在一个类里面的类就是内部类
- 内部类有什么用?
答:可以提供更好的封装性,内部类有更多的权限修饰符,封装性有了更多的控制
- 内部类的分类
-
静态内部类
-
实例内部类(成员内部类)
-
局部内部类
-
匿名内部类(重点)
1.8.1静态内部类(了解)
- 什么是静态内部类?
答:有static
修饰,属于外部类本身,会加载一次
- 静态内部类的成分
答:
-
类中有的成分它都有,静态内部类属于外部类本身,只会加载一次
-
所以它的特点与外部类是完全一样的,只是位置在别人里面而已
- 静态内部类的访问格式
答:外部类名称.内部类名称
- 静态内部类创建对象的格式
答:外部类名称.内部类名称 对象名称 = new 外部类名称.内部类构造器
- 静态内部类中是否可以直接访问外部类的静态成员?
答:可以的,外部类的静态成员只有一份,可以被共享
- 静态内部类中是否可以直接访问外部类的实例成员?
答:不可以,外部类的实例成员必须用外部类对象访问
请仔细理解下方代码,理解语法即可,静态内部类几乎不用!!!
public class InnerClass {
public static void main(String[] args) {
//外部类名称.内部类名称 对象名称 = new 外部类名称.内部类构造器
Outter.Inner in = new Outter.Inner();
in.setName(“张三”);
in.setAge(12);
in.show();
}
}
class Outter{
private double salary;
public static int age1 = 15;
// 静态内部类: 有static修饰,属于外部类本身,只会加载一次
public static class Inner{
private String name;
private int age;
public Inner() {
}
public Inner(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println(name +“是” + age + “岁”);
System.out.println(age1);
// 15
// System.out.println(salary); 报错
}
}
}
1.8.2实例内部类(了解)
- 什么是实例内部类?
答:无static
修饰的内部类,属于外部类的每个对象,跟着对象一起加载
- 实例内部类中的成分
答:实例内部类中不能定义静态成员,其他的都可以定义,可以定义常量
- 实例内部类的访问格式
答:外部类名称.内部类名称
- 实例内部类创建对象的格式
答:外部类名称.内部类名称 对象名称 = new 外部类构造器.new 内部类构造器
- 实例内部类中是否可以直接访问外部类的静态成员?
答:可以的,外部类的静态成员可以被共享访问
- 实例内部类中是否可以访问外部类的实例成员?
答:可以的,实例内部类属于外部类对象,可以直接访问当前外部类的实例成员
public class InnerClass {
public static void main(String[] args) {
// 实例内部类属于外部类对象。实例内部类的宿主是外部类对象!
Outter.Inner in = new Outter().new Inner();
in.show();
}
}
class Outter{
public static int age = 11;
private String salary;
// 实例内部类: 无static 修饰,属于外部类的对象
public class Inner{
private String name;
// 不能在实例内部类中定义静态成员!!
// public static String schoolName; 报错
// 可以定义常量
public static final String schoolName = “黑马”;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 实例方法
public void show(){
System.out.println(age);
System.out.println(salary);
}
}
}
1.8.3局部内部类(了解)
- 什么是局部内部类?
答:在方法,构造器,代码块,for循环中定义的内部类,就是局部内部类
- 局部内部类的成分
答:只能定义实例成员,不能定义静态成员,可以定义常量
- 局部内部类基本没啥用
public class InnerClass {
static {
// 局部内部类
abstract class A{
}
}
public static void main(String[] args) {
// 局部内部类
class A{
}
}
public static void test(){
// 局部内部类
class Animal{
}
// 局部内部类
class A extends Animal{
}
}
}
1.8.4匿名内部类(重点)
- 什么是匿名内部类?
答:就是一个没有名字的局部内部类
- 匿名内部类的作用
答:匿名内部类可以简化代码,是开发中常用的形式
- 匿名内部类的格式
new 类名|抽象类|接口(形参){
方法重写
}
- 匿名内部类的特点
答:1.匿名内部类是一个没有名字的内部类
2.匿名内部类一旦写出来,就会立即创建一个匿名内部类的对象返回
3.匿名内部类的对象的类型相当于是当前 new 的那个类型的子类类型