Java进阶之面向对象(二)——多态&接口
一、static关键字
1.1 static关键字概述
static是静态修饰符,用static修饰的变量被称为静态变量,修饰的方法被称为静态方法。
- 静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份(在方法区中的静态区),被类的所有对象共享。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。 - 静态方法
static 关键字用来声明独立于对象的方法,静态方法只能类的静态成员。
1.2 static关键字的使用
定义静态成员变量,目的是让其它存储在“静态存储区”,能够实现数据共享。
public static String country = "中国";
//给country重新赋值
stu1.country = "中华人民共和国";
System.out.println(stu2.country);//中华人民共和国
System.out.println(stu1.country);//中华人民共和国
非静态成员和静态成员的区别:
1.非静态成员在访问时只有一种方式
-
对象名.成员变量名
-
对象名.成员方法()
2.静态成员在访问时有两种访问方式
-
对象名.成员变量名
-
对象名.成员方法()
(类名一般是指的是父类名)
-
类名.成员变量名 (推荐)
-
类名.成员方法() (推荐)
推荐原因:因为使用时可以不需要创建对象直接使用,节省内存。
非静态方法和静态方法访问成员的区别:
-
非静态方法可以访问静态和非静态成员
-
静态方法只能直接访问静态成员(可以通过对象.成员间接访问)
不能直接访问的原因是:
- 静态方法比对象先加载,存储在静态区;此时非静态成员所在的对象还没有创建,所以不能直接访问非静态成员;一旦对象被被创建,就可以通过对象名.成员变量或者对象名.成员方法()的方式间接调用。
通常与final一起使用定义静态常量
常量名所有字母大写
public static final COUNTRY = "中国";
1.3 static小结
- 静态成员属于类
- 父类中的静态成员可以被子类继承
- static关键字不能修饰抽象方法和构造方法
- static关键字修饰的方法是静态方法,不能使用和对象有关的关键字,如this和super
- static可以修饰类,但这个类必须是内部类
二、接口
2.1 使用接口的目的
我们在定义类时,常常遇到除了所有子类共有特性之外,某些子类还有一些共有特性,但这些特性不能全部放到父类中,由于继承的单继承特点,我们不能再定义一个父类让这些子类继承,在这种情况下,为了弥补单继承的缺点,我们就可以使用接口。
2.2 接口概述
接口(英文:Interface),一种公共的规范标准,在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。
接口的特性:
- 接口中方法一般是抽象的,接口中的方法会被隐式的指定为
public abstract
(只能是public abstract
,其他修饰符都会报错) - 从JDK8开始,Java中的接口中可以存在使用default关键字修饰的方法
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为
public static final
变量(并且只能是 public,用 private 修饰会报编译错误) - 接口不能被实例化
- 实现类要么实现接口中所有的抽象方法,要么本身就是一个抽象类
- 一个类可以实现多个接口
- 一个接口可以继承多个接口
一个类可以实现多个接口
public class C implements B,A {
}
接口可以多继承
public interface D extends B,A {
}
2.3 接口中的成员
1.成员变量 静态常量
public static final int a = 10;
int b = 20; //编译后 public static final int b = 20;
public int c = 30; //编译后 public static final int c = 30;
2.成员方法 抽象方法(强制子类重写)
public abstract void show();
void show1();//编译后 public abstract void show1();
3.成员方法 默认方法(子类可以继承或重写,一般是继承,重写无意义)
public default void show2(){
System.out.println("默认方法");
}
4.静态方法 只属于本接口,不能继承,也不能被重写
public static void show3(){
System.out.println("接口中的静态方法");
}
三、多态
3.1 多态概述
多态是面向对象的三大特征之一,多态的目的是在父类或者接口中定义共有的方法,在子类或实现类中重写方法,用同一个引用类型,使用不同的实例来执行不同的操作,从而优化了代码。
3.2 多态的使用规则
- 必须有继承(实现)关系的父子类(接口实现类)
- 子类(实现类)要重写父类(接口)的方法
- 使用父类(接口)的引用指向子类(实现)的对象(向上转型)
多态示例:
public abstract class Worker {
//抽象方法
public abstract void work();
}
public class Sales extends Worker {
@Override
public void work() {
System.out.println("售货");
}
}
public class Cashier extends Worker {
@Override
public void work() {
System.out.println("收钱");
}
}
public class Manager {
/* //找售货员谈话
public void talk(Sales sales){
sales.work();
}
//找收银员谈话
public void talk(Cashier cashier){
cashier.work();
}*/
//找员工谈话
public void talk(Worker worker){
worker.work();
}
}
public class Test {
public static void main(String[] args) {
//接收子类的实例
Worker w = new Cashier();
Manager m = new Manager();
m.talk(w); //调用谈话方法
}
}
3.3 多态中成员访问特点
成员变量 编译和执行都看左边
成员方法 编译看左边,执行看右边(成员方法有重写,成员变量没有)
public class Test {
public static void main(String[] args) {
Fu f = new Zi();//4
System.out.println(f.num);
Zi z = new Zi();//5
System.out.println(z.num);
f.show();//ZiShow
z.show();//ZiShow
}
}
class Fu {
int num = 4;
void show(){
System.out.println("FuShow");
}
}
class Zi extends Fu{
int num = 5;
void show(){
System.out.println("ZiShow");
}
}
3.4 多态的应用形式
多态的三种形式:
1.父类多态 普通类作为父类
2.抽象类多态 抽象类作为父类
3.接口多态 接口作为父类
多态的三种使用方式:
- 变量类型的多态 Worker w = new Sales();
- 形参类型的多态 public void talk(Worker w){}
- 返回值类型的多态 public Worker talk(){ return new Sales}
3.5 多态的转型
向上转型:从子类到父类,父类引用指向子类对象
Sales类继承了Worker类
Worker w = new Sales();
向下转型:从父类到子类,父类引用转为子类对象
Sales类继承了Worker类
Worker w = new Sales();
//判断前者中装的是否为后者的类型
if(w instanceof Sales){
Sales s = (Sales) w;