1.final关键字
final修饰的不能被修改或覆盖,常修饰类,方法,变量
final的特点:
(1)final修饰类时,该类不能被继承
(2)final修饰方法时,该方法不能被重写
(3)final修饰变量时,该变量不能被重新赋值,即变成了常量
2. 多态
多态:某一个事物,在不同时刻表现出来的不同状态
多态的前提:
(1)有继承关系
(2)要有方法重写
(3)要有父类引用指向子类对象 即 父 f = new 子();
多态中的成员访问特点:
(1)成员变量:编译,运行看父类中的(左边)
(2)构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
(3)成员方法:编译看父类,运行看子类(父类的被覆盖了)
(4)静态方法:编译,运行看父类中的(左边) (静态和类相关,算不上重写,所以还是访问左边的)
多态的好处:
(1)继承保证了代码的维护性
(2)提高了代码的扩展性
多态的种类:
(1)具体类多态(少)
(2)抽象类多态(常用)
(3)接口多态(最常用)
class Animal{
public void eat() {
System.out.println("eat");
}
public void sleep() {
System.out.println("sleep");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃肉");
}
public void sleep() {
System.out.println("狗站着睡");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void sleep() {
System.out.println("猫躺着睡");
}
}
//提高了扩展性,因为日后即便再加入其他动物,也只需要定义好动物的类,即可用AnimalTool调用执行
class AnimalTool {
private AnimalTool() {}
public static void useAnimal(Animal a) {
a.eat();
a.sleep();
}
}
public class ExtendsDemo {
public static void main(String[] args) {
//多态
Animal c1 = new Cat();
Animal c2 = new Cat();
Animal d1 = new Dog();
AnimalTool.useAnimal(c1);
AnimalTool.useAnimal(c2);
AnimalTool.useAnimal(d1);
}
}
多态的弊端:不能使用子类的特有功能
但是可以把父类的应用强制转换为子类的引用,即向下转型
对象间的转型问题:
(1)向上转型:把子变成父 如 Fu f = new Zi();
(2)向下转型:把父变成子 如 Zi z = (Zi) f;
多态猫狗实例:
class Animal{
public void eat() {
System.out.println("eat");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃肉");
}
public void lookDoor() {
System.out.println("狗看门");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
public class DuoTaiTest {
public static void main(String[] args) {
//定义为狗,向上转型
Animal a = new Dog();
a.eat();
System.out.println("--------");
//还原成狗,向下转型
Dog d = (Dog)a;
d.eat();
d.lookDoor();
System.out.println("--------");
//定义为猫,向上转型
a = new Cat();
a.eat();
System.out.println("--------");
//还原成猫,向下转型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
3. 抽象类
把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类
抽象类的特点:
(1)抽象类和抽象方法必须用abstract关键字修饰 格式:abstract class 类名 {} public abstract void eat();
(2)抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
(3)抽象类不能被实例化,因为他不是具体的,但是可以通过多态的方式实例化 例如:Animal a = new Cat();
(4)抽象类的子类,要么是抽象类,要么重写抽象类中的所有抽象方法。
抽象类的成员特点:
(1)成员变量:既可以是变量也可以是常量
(2)构造方法:有,用于子类访问父类数据的初始化
(3)成员方法:既可以是抽象的,也可以是非抽象的
抽象方法的成员特性:
(1)抽象方法:强制要求子类做的事情
(2)非抽象方法:子类继承的事情,提高代码的复用性
abstract class Animal{
private String name;
private int age;
public Animal() {}
public Animal(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 abstract void eat();
}
class Dog extends Animal{
public Dog() {}
public Dog(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal{
public Cat() {}
public Cat(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("猫吃鱼");
}
}
public class ExtendsDemo {
public static void main(String[] args) {
//方式1
Dog d = new Dog();
d.setName("哈哈");
d.setAge(3);
System.out.println(d.getName()+"---"+d.getAge());
d.eat();
//方式2
Dog d2 = new Dog("旺财",4);
System.out.println(d2.getName()+"---"+d2.getAge());
d2.eat();
//多态方式,不是为了程序的扩展性,不需要用此种方式
Animal a = new Dog("二哈",7);
System.out.println(a.getName()+"---"+a.getAge());
a.eat();
}
}
哈哈---3
狗吃肉
旺财---4
狗吃肉
二哈---7
狗吃肉
抽象类的几个问题:
(1)abstract 不能和 private 共存,会冲突
(2)和final冲突
(3)和static在一起使用无意义
4. 接口
接口特点:
(1)接口用关键字Interface表示 格式: interface 接口名 {}
(2)类实现接口用Implements表示 格式: class 类名 implements 接口名 {}
(3)接口不能实例化 (但是可以通过多态的方式,由具体的子类实例化)
(4)接口的子类:要么是抽象类(意义不大,因为抽象类实例化还要在建立一个子类),要么是重写接口中的所有抽象方法
接口成员特点:
(1)成员变量只能是常量,并且是静态的,默认修饰符 public static final ,建议自己手动给出
(2)构造方法:没有,因为接口主要是扩展功能的,没有具体存在。类Object是类层次结构的根类,每个类都用Object作为超类
(3)成员方法:只能是抽象方法,默认修饰符 public abstract
interface Inter{
//实际为public static final num
public int num = 10;
public final int num2 = 20;\
//实际为public abstract void show()
abstract void show();
}
//接口名+Impl是接口的实现类格式
//本质为class InterImpl extends object implements Inter
class InterImpl implements Inter{
public InterImpl() {
super();
}
public void show() {}
}
public class InterfaceDemo {
public static void main(String[] args) {
//创建对象
Inter i = new InterImpl();
}
}
关系:
(1)类与类:继承关系,只能单继承,但是可以多层继承
(2)类与接口:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
(3)接口与接口:继承关系,可以单继承,也可以多继承
抽象类和接口的设计理念区别:
(1)抽象类:被继承体现的是:“is a ”的关系。抽象类中定义的是该继承体系的共性功能
(2)接口:被实现体现的是:“like a”的关系。接口中定义的是该继承体系的扩展功能。
interface SpeakEnglish {
public abstract void speak();
}
//定义人类抽象类
abstract class Person {
private String name;
private int age;
public Person() {}
public Person(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 sleep() {
System.out.println("要睡觉了");
}
//吃饭
public abstract void eat();
}
//定义运动员抽象类
abstract class Player extends Person {
public Player() {}
public Player(String name,int age) {
super(name,age);
}
//学习
public abstract void study();
}
//定义教练抽象类
abstract class Coach extends Person {
public Coach() {}
public Coach(String name,int age) {
super(name,age);
}
//教
public abstract void teach();
}
//定义乒乓球运动员具体类
class PingPangPlayer extends Player implements SpeakEnglish {
public PingPangPlayer() {}
public PingPangPlayer(String name,int age) {
super(name,age);
}
//吃
public void eat() {
System.out.println("乒乓球运动员吃鱼香肉丝");
}
//学习
public void study() {
System.out.println("乒乓球运动员学习如何发球");
}
//说英语
public void speak() {
System.out.println("乒乓器运动员说英语");
}
}
//定义篮球运动员具体类
class BasketballPlayer extends Player {
public BasketballPlayer() {}
public BasketballPlayer(String name,int age) {
super(name,age);
}
//吃
public void eat() {
System.out.println("篮球运动员吃牛肉");
}
//学习
public void study() {
System.out.println("篮球运动员学习如何运球");
}
}
//定义乒乓球教练具体类
class PingPangCoach extends Coach implements SpeakEnglish {
public PingPangCoach() {}
public PingPangCoach(String name,int age) {
super(name,age);
}
//吃
public void eat() {
System.out.println("乒乓球教练吃白菜");
}
//学习
public void teach() {
System.out.println("乒乓球教练教学习如何发球");
}
//说英语
public void speak() {
System.out.println("乒乓器教练说英语");
}
}
//定义篮球教练具体类
class BasketballCoach extends Coach {
public BasketballCoach() {}
public BasketballCoach(String name,int age) {
super(name,age);
}
//吃
public void eat() {
System.out.println("篮球教练吃鸡肉");
}
//学习
public void teach() {
System.out.println("篮球教练教如何运球");
}
}
class InterfaceDemo {
public static void main(String[] args) {
//测试运动员
//乒乓球运动员
PingPangPlayer p = new PingPangPlayer();
p.setName("大米");
p.setAge(18);
System.out.println(p.getName()+"---"+p.getAge());
p.eat();
p.sleep();
p.study();
p.speak();
//篮球运动员
BasketballPlayer b = new BasketballPlayer();
b.setName("便士");
b.setAge(22);
System.out.println(b.getName()+"---"+b.getAge());
b.eat();
b.sleep();
b.study();
}
}
大米---18
乒乓球运动员吃鱼香肉丝
要睡觉了
乒乓球运动员学习如何发球
乒乓器运动员说英语
便士---22
篮球运动员吃牛肉
要睡觉了
篮球运动员学习如何运球