Java基础第三弹---继承与多态

继承、抽象类

1.继承

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要
继承那一个类即可。 多个类可以称为子类,单独那一个类称为父类超类(superclass或者基类

  • 定义

继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接
访问父类中的非私有的属性和行为。

  • 优点
    • 提高代码的复用性
    • 类与类之间产生了关系,是多态的前提
1.1 继承的格式

通过 extends 关键字,可以声明一个子类继承另外一个父类。

class 父类 {
...
}
class 子类 extends 父类 {
...
}
//定义员工类Employee,做为父类
class Employee {
	String name; // 定义name属性
	// 定义员工的工作方法
	public void work() {
		System.out.println("尽心尽力地工作");
	}
} 

//定义讲师类Teacher继承员工类Employee
class Teacher extends Employee {
	// 定义一个打印name的方法
	public void printName() {
		System.out.println("name=" + name);
	}
} 

//定义测试类
public class ExtendDemo01 {
	public static void main(String[] args) {
		// 创建一个讲师类对象
		Teacher t = new Teacher();
		// 为该员工类的name属性进行赋值
		t.name = "小明";
		// 调用该员工的printName()方法
		t.printName(); // name = 小明
		// 调用Teacher类继承来的work()方法
		t.work(); // 尽心尽力地工作
	}
}
1.2 继承后的特点-成员变量
  • 成员变量不重名

如果子类父类中出现不重名的成员变量,这时的访问是没有影响的

class Fu {
	// Fu中的成员变量。
	int num = 5;
} 
cass Zi extends Fu {
	// Zi中的成员变量
	int num2 = 6;
	// Zi中的成员方法
	public void show() {
		// 访问父类中的num,
		System.out.println("Fu num="+num); // 继承而来,所以直接访问。
		// 访问子类中的num2
		System.out.println("Zi num2="+num2);
	}
} 
class ExtendDemo02 {
	public static void main(String[] args) {
		// 创建子类对象
		Zi z = new Zi();
		// 调用子类中的show方法
		z.show();//Fu num = 5  Zi num2 = 6
	}
}
  • 成员变量重名

如果子类父类中出现重名的成员变量,这时的访问是有影响的

class Fu {
	// Fu中的成员变量。
	int num = 5;
} 
class Zi extends Fu {
	// Zi中的成员变量
	int num = 6;
	public void show() {
		// 访问父类中的num
		System.out.println("Fu num=" + num);
		// 访问子类中的num
		System.out.println("Zi num=" + num);
	}
} 
class ExtendsDemo03 {
	public static void main(String[] args) {
		// 创建子类对象
		Zi z = new Zi();
		// 调用子类中的show方法
		z.show();//Fu num = 6  Zi num = 6
	}
} 

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰父类成员变量,类似于之前学过的this

  • 格式
super.父类成员变量名
class Zi extends Fu {
	// Zi中的成员变量
	int num = 6;
	public void show() {
		//访问父类中的num
		System.out.println("Fu num=" + super.num);
		//访问子类中的num
		System.out.println("Zi num=" + this.num);
	}
}
1.3 继承后的特点-成员方法
  • 成员方法不重名

如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对
应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。

class Fu{
	public void show(){
		System.out.println("Fu类中的show方法执行");
	}
} 
class Zi extends Fu{
	public void show2(){
		System.out.println("Zi类中的show2方法执行");
	}
} 
public class ExtendsDemo04{
	public static void main(String[] args) {
		Zi z = new Zi();
		//子类中没有show方法,但是可以找到父类方法去执行
		z.show();
		z.show2();
	}
}
  • 成员方法重名——重写(Override)

**方法重写:**子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效
果,也称为重写或者复写。声明不变,重新实现。

class Fu {
	public void show() {
		System.out.println("Fu show");
	}
}
class Zi extends Fu {
	//子类重写了父类的show方法
	public void show() {
		System.out.println("Zi show");
	}
} 
public class ExtendsDemo05{
	public static void main(String[] args) {
		Zi z = new Zi();
		// 子类中有show方法,只执行重写后的show方法
		z.show(); // Zi show
	}
}
1.4 继承后的特点-构造方法
  • 构造方法的定义格式和作用:
    • 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
    • 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super(),表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
class Fu {
	private int n;
	Fu(){
		System.out.println("Fu()");
	}
}
class Zi extends Fu {
	Zi(){
	// super(),调用父类构造方法
	super();
	System.out.println("Zi()");
	}
} 
public class ExtendsDemo07{
	public static void main (String args[]){
		Zi zi = new Zi();//Fu() Zi()
	}
}
1.5 super和this
  • super和this的含义

    • super :代表父类的存储空间标识(可以理解为父亲的引用)。
    • this :代表当前对象的引用(谁调用就代表谁)。
  • super和this的用法

访问成员

this.成员变量 ‐‐ 本类的
super.成员变量 ‐‐ 父类的
    
this.成员方法名() ‐‐ 本类的
super.成员方法名() ‐‐ 父类的
class Animal {
	public void eat() {
		System.out.println("animal : eat");
	}
} 
class Cat extends Animal {
	public void eat() {
		System.out.println("cat : eat");
	} 
	public void eatTest() {
		this.eat(); // this 调用本类的方法
		super.eat(); // super 调用父类的方法
	}
} 
public class ExtendsDemo08 {
	public static void main(String[] args) {
		Animal a = new Animal();
		a.eat();
		Cat c = new Cat();
		c.eatTest();
	}
}
输出结果为:
animal : eat
cat : eat
animal : eat

访问构造方法

this(...) ‐‐ 本类的构造方法
super(...) ‐‐ 父类的构造方法
1.6 继承的特点
  • Java只支持单继承,不支持多继承。
//一个类只能有一个父类,不可以有多个父类。
class C extends A{} //ok
class C extends A,B... //error
  • Java支持多层继承(继承体系)。
class A{}
class B extends A{}
class C extends B{}

2.抽象类

父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有
意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法
的类就是抽象类

  • 定义
    • 抽象方法 : 没有方法体的方法。
    • 抽象类:包含抽象方法的类
2.1 abstract
  • 抽象方法

使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。

格式:

修饰符 abstract 返回值类型 方法名 (参数列表)
public abstract void run()
  • 抽象类

如果一个类包含抽象方法,那么该类必须是抽象类。

定义:

abstract class 类名字 {
}
public abstract class Animal {
	public abstract void run()}
  • 抽象的使用

继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父
类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。

接口、多态

1.接口

接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型

  • 引用数据类型:数组,类,接口。

接口的使用,它不能创建对象,但是可以被实现( implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。

1.1 定义格式
public interface 接口名称 {
	// 抽象方法
	// 默认方法
	// 静态方法
	// 私有方法
}
  • 含有抽象方法

抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。

public interface InterFaceName {
	public abstract void method();
}
  • 含有默认方法和静态方法

默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
静态方法:使用 static 修饰,供接口直接调用。

public interface InterFaceName {
	public default void method() {
		// 执行语句
	} 
	public static void method2() {
		// 执行语句
	}
}
  • 含有私有方法和私有静态方法

私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。

public interface InterFaceName {
	private void method() {
		// 执行语句
	}
}
1.2 基本的实现
1.2.1 实现

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。

  • 非抽象子类实现接口:
    • 必须重写接口中所有抽象方法。
    • 继承了接口的默认方法,即可以直接调用,也可以重写。
class 类名 implements 接口名 {
	// 重写接口中抽象方法【必须】
	// 重写接口中默认方法【可选】
}
1.2.2 抽象方法的使用

(必须全部实现)

  • 定义接口:
public interface LiveAble {
	// 定义抽象方法
	public abstract void eat();
	public abstract void sleep();
}
  • 定义实现类:
public class Animal implements LiveAble {
	@Override
	public void eat() {
		System.out.println("吃东西");
	} 
	@Override
	public void sleep() {
		System.out.println("晚上睡");
	}
}
  • 定义测试类:
public class InterfaceDemo {
	public static void main(String[] args) {
		// 创建子类对象
		Animal a = new Animal();
		// 调用实现后的方法
		a.eat();//吃东西
		a.sleep();//晚上睡
	}
}
1.2.3 默认方法的使用

(可以继承、可以重写,二选一,但是只能通过实现类的对象来调用)

1.继承默认方法

  • 定义接口:
public interface LiveAble {
	public default void fly(){
		System.out.println("天上飞");
	}
}
  • 定义实现类:
public class Animal implements LiveAble {
	// 继承,什么都不用写,直接调用
}
  • 定义测试类:
public class InterfaceDemo {
	public static void main(String[] args) {
		// 创建子类对象
		Animal a = new Animal();
		// 调用默认方法
		a.fly();//天上飞
	}
}

2.重写默认方法

  • 定义接口:
public interface LiveAble {
	public default void fly(){
		System.out.println("天上飞");
	}
}
  • 定义实现类:
public class Animal implements LiveAble {
	@Override
	public void fly() {
		System.out.println("自由自在的飞");
	}
}
  • 定义测试类:
public class InterfaceDemo {
	public static void main(String[] args) {
		// 创建子类对象
		Animal a = new Animal();
		// 调用重写方法
		a.fly();//自由自在的飞
	}
}
1.2.4 静态方法的使用

静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用。

  • 定义接口:
public interface LiveAble {
	public static void run(){
		System.out.println("跑起来~~~");
	}
}
  • 定义实现类:
public class Animal implements LiveAble {
	// 无法重写静态方法
}
  • 定义测试类:
public class InterfaceDemo {
	public static void main(String[] args) {
		// Animal.run(); // 【错误】无法继承方法,也无法调用
		LiveAble.run(); //跑起来~~~
	}
}
1.2.5 私有方法的使用
  • 私有方法:只有默认方法可以调用。
  • 私有静态方法:默认方法和静态方法可以调用。

如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法
去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。

  • 定义接口
public interface LiveAble {
	default void func(){
		func1();
		func2();
	} 
	private void func1(){
		System.out.println("跑起来~~~");
	} 
	private void func2(){
		System.out.println("跑起来~~~");
	}
}
1.3 接口的多实现

在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接
口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

  • 实现
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
	// 重写接口中抽象方法【必须】
	// 重写接口中默认方法【不重名时可选】
}
1.3.1 抽象方法

接口中,有多个抽象方法时,实现类必须重写所有抽象方法**。如果抽象方法有重名的,只需要重写一次。**

  • 定义多个接口:
interface A {
	public abstract void showA();
	public abstract void show();
} 
interface B {
	public abstract void showB();
	public abstract void show();
}
  • 定义实现类:
public class C implements A,B{
	@Override
	public void showA() {
		System.out.println("showA");
	}
	@Override
	public void showB() {
		System.out.println("showB");
	} 
	@Override
	public void show() {
		System.out.println("show");
	}
}
1.3.2 默认方法

接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次。

  • 定义多个接口:
interface A {
public default void methodA(){}
public default void method(){}
} 
interface B {
public default void methodB(){}
public default void method(){}
}
  • 定义实现类:
public class C implements A,B{
	@Override
	public void method() {
		System.out.println("method");
	}
}
1.3.3 静态方法

接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法。

1.3.4 优先级问题

当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执
行父类的成员方法。

  • 定义接口:
interface A {
	public default void methodA(){
		System.out.println("AAAAAAAAAAAA");
	}
}
  • 定义父类:
class D {
	public void methodA(){
		System.out.println("DDDDDDDDDDDD");
	}
}
  • 定义子类:
class C extends D implements A {
	// 未重写methodA方法
}
  • 定义测试类:
public class Test {
	public static void main(String[] args) {
		C c = new C();
		c.methodA();//DDDDDDDDDDDD
	}
}
1.4 接口的多继承

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继
承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。

  • 定义父接口:
interface A {
	public default void method(){
		System.out.println("AAAAAAAAAAAAAAAAAAA");
	}
} 
interface B {
	public default void method(){
		System.out.println("BBBBBBBBBBBBBBBBBBB");
	}
}
  • 定义子接口:
interface D extends A,B{
	@Override
	public default void method() {
		System.out.println("DDDDDDDDDDDDDD");
	}
}
1.5 其他成员特点
  • 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。
  • 接口中,没有构造方法,不能创建对象。
  • 接口中,没有静态代码块。

2.多态

多态是继封装、继承之后,面向对象的第三大特性。

  • 多态: 是指同一行为,具有多个不同表现形式。
2.1 多态的体现

格式(父类类型:指子类对象继承的父类类型,或者实现的父接口类型。 )

父类类型 变量名 = new 子类对象;
变量名.方法名();
Fu f = new Zi();
f.method();

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。

定义父类:

public abstract class Animal {
	public abstract void eat();
}

定义子类:

class Cat extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	}
}
class Dog extends Animal {
	public void eat() {
	System.out.println("吃骨头");
	}
}

定义测试类:

public class Test {
	public static void main(String[] args) {
		// 多态形式,创建对象
		Animal a1 = new Cat();
		// 调用的是 Cat 的 eat
		a1.eat();
		// 多态形式,创建对象
		Animal a2 = new Dog();
		// 调用的是 Dog 的 eat
		a2.eat();
	}
}
2.3 多态的优点

实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。

定义父类:

public abstract class Animal {
	public abstract void eat();
}

定义子类:

class Cat extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	}
} 
class Dog extends Animal {
	public void eat() {
		System.out.println("吃骨头");
	}
}

定义测试类:

public class Test {
	public static void main(String[] args) {
		// 多态形式,创建对象
		Cat c = new Cat();
		Dog d = new Dog();
		// 调用showCatEat
		showCatEat(c);
		// 调用showDogEat
		showDogEat(d);
		//以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代而执行效果一致
		showAnimalEat(c);
		showAnimalEat(d);
	} 
    public static void showCatEat (Cat c){
		c.eat();
	} 
    public static void showDogEat (Dog d){
		d.eat();
	} 
    public static void showAnimalEat (Animal a){
		a.eat();
	}
}
2.4 引用类型的转换

多态的转型分为向上转型与向下转型两种。

  • 向上转型

多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。 当父类引用指向一个子类对象时,便是向上转型。

父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();

向下转型

  • 向下转型

父类类型向子类类型向下转换的过程,这个过程是强制的。一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。

子类类型 变量名 = (子类类型) 父类变量名;:Cat c =(Cat) a;

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

定义类:

abstract class Animal {
	abstract void eat();
	} 
class Cat extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	} 
    public void catchMouse() {
		System.out.println("抓老鼠");
	}
} 
class Dog extends Animal {
	public void eat() {
		System.out.println("吃骨头");
	} 
    public void watchHouse() {
		System.out.println("看家");
	}
}

定义测试类:

public class Test {
	public static void main(String[] args) {
		// 向上转型
		Animal a = new Cat();
		a.eat(); // 调用的是 Cat 的 eat
		// 向下转型
		Cat c = (Cat)a;
		c.catchMouse(); // 调用的是 Cat 的 catchMouse
	}
}
  • 转型的异常

Java提供了 instanceof 关键字,给引用变量做类型的校验。

变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false

final、权限、内部类、引用类型

1.final关键字

Java提供了 final 关键字,用于修饰不可改变内容。

  • final: 不可改变。可以用于修饰类、方法和变量。
    • 类:被修饰的类,不能被继承。
    • 方法:被修饰的方法,不能被重写。
    • 变量:被修饰的变量,不能被重新赋值。
1.1 使用方式
  • 修饰类
final class 类名 {
}
  • 修饰方法
修饰符 final 返回值类型 方法名(参数列表){
	//方法体
}
  • 修饰变量

局部变量——基本类型

基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。

public class FinalDemo1 {
	public static void main(String[] args) {
		// 声明变量,使用final修饰
		final int a;
		// 第一次赋值
		a = 10;
		// 第二次赋值
		a = 20; // 报错,不可重新赋值
	}
}

局部变量——引用类型

引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改。

public class FinalDemo2 {
	public static void main(String[] args) {
		// 创建 User 对象
		final User u = new User();
		// 创建 另一个 User对象
		u = new User(); // 报错,指向了新的对象,地址值改变。
		// 调用setName方法
		u.setName("张三"); // 可以修改
	}
}

成员变量

成员变量涉及到初始化的问题,初始化方式有两种,只能二选一 :

显示初始化

public class User {
	final String USERNAME = "张三";
	private int age;
}

构造方法初始化

public class User {
	final String USERNAME ;
	private int age;
	public User(String username, int age) {
		this.USERNAME = username;
		this.age = age;
	}
}

被final修饰的常量名称,一般都有书写规范,所有字母都大写

2.权限修饰符

Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限。

  • public:公共的。
  • protected:受保护的
  • default:默认的
  • private:私有的

3.内部类

3.1 概述

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

  • 成员内部类

定义在类中方法外的类。

class 外部类 {
	class 内部类{
	}
}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类 Car 中包含发动机
类 Engine ,这时, Engine 就可以使用内部类来描述,定义在成员位置。

class Car { //外部类
	class Engine { //内部类
	}
}
  • 访问特点
    • 内部类可以直接访问外部类的成员,包括私有成员。
    • 外部类要访问内部类的成员,必须要建立内部类的对象。
外部类名.内部类名 对象名 = new 外部类型().new 内部类型()

定义类:

public class Person {
	private boolean live = true;
	class Heart {
		public void jump() {
			// 直接访问外部类成员
			if (live) {
				System.out.println("心脏在跳动");
			} else {
				System.out.println("心脏不跳了");
			}
		}
	} 
    public boolean isLive() {
		return live;
	} 
    public void setLive(boolean live) {
		this.live = live;
	}
}

定义测试类:

public class InnerDemo {
	public static void main(String[] args) {
		// 创建外部类对象
		Person p = new Person();
		// 创建内部类对象
		Heart heart = p.new Heart();
		// 调用内部类方法
		heart.jump();
		// 调用外部类方法
		p.setLive(false);
		// 调用内部类方法
		heart.jump();
	}
}
输出结果:
心脏在跳动
心脏不跳了
3.2 匿名内部类(重点)

匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象。开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,

  1. 定义子类
  2. 重写接口中的方法
  3. 创建子类对象
  4. 调用重写后的方法

我们的目的,最终只是为了调用方法,那么能不能简化一下 。匿名内部类就是做这样的快捷方式。

  • 前提: 匿名内部类必须继承一个父类或者实现一个父接口
  • 格式
new 父类名或者接口名(){
	// 方法重写
	@Override
	public void method() {
	// 执行语句
	}
};
  • 使用方法(以接口为例)

定义接口:

public abstract class FlyAble{
	public abstract void fly();
}

创建匿名内部类,并调用:

public class InnerDemo {
	public static void main(String[] args) {
		//1.等号右边:是匿名内部类,定义并创建该接口的子类对象
		//2.等号左边:是多态赋值,接口类型引用指向子类对象
		FlyAble f = new FlyAble(){
			public void fly() {
				System.out.println("我飞了~~~");
			}
		};
		//调用 fly方法,执行重写后的方法
		f.fly();
	}
}

通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。

public class InnerDemo2 {
	public static void main(String[] args) {
		FlyAble f = new FlyAble(){
			public void fly() {
				System.out.println("我飞了~~~");
			}
		};
		// 将f传递给showFly方法中
		showFly(f);
	} 
    public static void showFly(FlyAble f) {
		f.fly();
	}
}

两步合为一步

public class InnerDemo3 {
	public static void main(String[] args) {
		//创建匿名内部类,直接传递给showFly(FlyAble f)
		showFly( new FlyAble(){
			public void fly() {
				System.out.println("我飞了~~~");
			}
		});
	} 
    public static void showFly(FlyAble f) {
		f.fly();
	}
}

4.引用类型用法总结

  • class作为成员变量

类作为成员变量时,对它进行赋值的操作,实际上,是赋给它该类的一个对象。

  • interface作为成员变量

  • interface作为方法参数和返回值类型

写在最后:最近每天都在总结复习java基础的东西,自己学的还是不够扎实,争取每天都会总结好一部分,最后总结完成后还会发一个总的java基础总结,敬请期待呀!嘻嘻!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值