【Java基础10】内部类和多态

1.内部类 在java中可以把类定义在另个类的内部,我们称之为内部类,外层的类为外部类。在一个类的内部有一个完整的结构,而这个内部结构只为外部类提供服务。内部类可以更方便的访问外部类成员,内部类更好的提供封装性,可以用权限修饰符更好的控制。

// 格式 public class 类名 { // 内部类 权限修饰符 [static] class 内部类名称 { ... } }

1.1 静态内部类 静态内部类是使用static修饰的类,属于外部类的一部分。他的特点和普通类一样,只是位置不同。
// 格式 public class Outer { public static class Inner { ... } }

public class StaticInnerClass1 { public static String str = "Version 1.0"; public static int num = 10; private String name; public static class Inner { private String type; private int age; public Inner() { }public Inner(String type, int age) { this.type = type; this.age = age; }public void show() { System.out.println(str); System.out.println(num); }public String getType() { return type; }public void setType(String type) { this.type = type; }public int getAge() { return age; }public void setAge(int age) { this.age = age; } }public String getName() { return name; }public void setName(String name) { this.name = name; }public static void main(String[] args) { // 内部类实例化 StaticInnerClass1.Inner inner = new StaticInnerClass1.Inner(); inner.show(); } }

注意:
静态内部类可以直接访问外部类静态成员
静态内部类不能直接访问外部实例成员
1.2 成员内部类 成员内部类和静态内部类相似,只是不加static关键字修饰符。在jdk1.6之前不能在成员内部类定义静态成员,之后版本可以定义。
// 格式 修饰符 class 类名 { ... 修饰符 class 内部类类名 { ... } }

// 成员内部类调用 外部类.内部类 对象名 = new 外部类构造器().new 内部类构造器()

// 示例 public class MemberInnerClass {public static int flag = 0; private String name; private int age; public MemberInnerClass() { }public MemberInnerClass(String name, int age) { this.name = name; this.age = age; }public class Inner {private String sex; private int num; public Inner() { }public Inner(String sex, int num) { this.sex = sex; this.num = num; }public void show() { System.out.println(flag); System.out.println(name); System.out.println(age); System.out.println(sex); System.out.println(num); }public String getSex() { return sex; }public void setSex(String sex) { this.sex = sex; }public int getNum() { return num; }public void setNum(int num) { this.num = num; } }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 static void main(String[] args) { MemberInnerClass.Inner inner = new MemberInnerClass("张三", 18).new Inner("男", 1); inner.show(); } }

特点:
  • 属于外部类的对象,与类特征一致
  • 不能创建静态成员,静态成员需要使用final
  • 可以直接访问外部成员和静态成员
1.3 局部内部类 这是一个比较很怪异的语法,正常情况很少使用,只做了解。
局部内部类放在代码块、构造器和方法中。
// 示例 public class PartialInnerClass { { class Dog{ }Dog dog = new Dog(); }public PartialInnerClass() { class Cat{ } Cat cat = new Cat(); }public static void main(String[] args) { class Pig{ } Pig pig = new Pig(); } }

1.4 匿名内部类 匿名内部类本质上就是一个没有名称的局部内部类,主要定义在方法和代码块中。最主要的目标是为了简化代码。
// 格式 new (类|抽象类|接口) { ... }

特点:
匿名内部类是一个没有名称内部类
匿名内部类编写出来即创建出一个匿名对象
匿名内部类创建出来的为当前类的子类
// 示例 public interface AnonymousInnerClass {void show(); static void main(String[] args) { AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass() { @Override public void show() { System.out.println("匿名类创建"); } }; anonymousInnerClass.show(); } }

从上面可以看出,AnonymousInnerClass貌似直接创建了对象,但实际并非如此。anonymousInnerClass实例获得到的对象其实是接口的实现类或者子类。这是匿名内部类的特性,创建即生成子类。子类对象可以直接赋值给父类,这就是多态,面对对象的三大特性之一,接下来我们即将介绍这部分内容。
1.5 内部类示例 以下示例显示了如何调用局部变量、成员变量和外部类成员变量
public class Other {private int number = 10; public class Inner { private int number = 5; public void show() { int number = 2; // 2 System.out.println(number); // 5 System.out.println(this.number); // 10 System.out.println(Other.this.number); } }public static void main(String[] args) { Inner inner = new Other().new Inner(); inner.show(); } }

2. 多态 同类型对象,在执行相同行为时会出现不同的特征。举一个简单的例子,狗和猫都可以抽象成类,这些类又可以是动物类的子类。那么猫和狗都是动物的子类,都来实现叫声,当执行不同子类叫声行为时,结果就会不一样。
2.1 格式及成员访问特点
// 格式 类 对象 = new 子类()接口 对象 = new 实现类()

访问特点:
  • 变量:编译和调用都看父类
  • 方法:编译看父类,调用看子类
2.2 多态优劣 优:
  • 解耦、便于扩展和维护
  • 形参可以定义父类,传递实参为子类即可,体现出扩展性。
劣:
  • 多态情况下,不能使用子类的独有功能
2.3 类型转换 自动类型转换:子类或者实现类实例对象可以直接赋值给父类或接口
强制类型转换:类似基础类型强制转换,子类 对象变量 = (子类)父类类型变量,此种转换也解决了不能使用子类独立功能弊端。
强制类型转换问题:
- 如果子类不是父类真正子类,则会抛出异常ClassCastException - 强制类型转换一般使用instanceof进行判断

// 格式 类变量 instanceof 类名 // 返回结果为boolean类型

2.4 示例
// 接口 public interface Animal { void bark(); }public class Cat implements Animal{ @Override public void bark() { System.out.println("小猫发出喵喵叫声。。。"); } }public class Dog implements Animal { @Override public void bark() { System.out.println("小狗发出汪汪汪叫声。。。"); } }public class Demo { public static void getBark(Animal animal) { animal.bark(); }public static void main(String[] args) { // 发出喵叫 getBark(new Cat()); // 发出狗叫 getBark(new Dog()); } }

本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!
【【Java基础10】内部类和多态】源码 【GitHub】 【码云】

    推荐阅读