1、final关键字是最终的意思,可以修饰类、方法和变量。
final修饰类不能被继承。修饰方法不能被重写。修饰变量是常量
例如:
final class Father{}//final修饰类将不能被继承
class Father{
/*
public final void show(){
System.out.println("father");
}
}
*/
//加上final后就不能被Son重写了,因为final是最终的
public void show(){
System.out.println("father");
}
}
class Son extends Father{
public void show() {
System.out.println("son");
}
}
public class Main {
public static void main(String[] args) {
Son s=new Son();
s.show();
}
}
上述例子中Father中的show被Son中的show覆盖了,为了解决这个问题,引入了final。
2、多态同一个对象在不同时刻表象出来的不同状态。
多态的前提,有继承或者实现关系。有方法重写。有父类或者父接口引用指向子类对象。
多态的分类
具有类多态格式,class Fu{}。class Zi extends Fu{}。Fu f=new Zi();
抽象类多态,abstract class Fu{}。class Zi extends Fu{}。Fu f=new Zi();
接口多态,interface Fu{}。class Zi implements Fu{}。Fu f=new Zi();
多肽中的成员访问特点,成员方法有重写,所以运行是儿子的内容。
例如:
class Father{
public int num=100;
public int num1=1000;
public void show() {
System.out.println("father");
}
public static void function() {
System.out.println("function father");
}
}
class Son extends Father{
public int num=200;
public int num2=2000;
public void show() {
System.out.println("Son");
}
public static void function() {
System.out.println("function Son");
}
}
public class Main {
public static void main(String[] args) {
//成员变量,编译看左边,运行看左边
Father s=new Son();
System.out.println(s.num);
System.out.println(s.num1);
//System.out.println(s.num2);找不到符号,编译看左边即看Father类
//构造方法,创建子类的时候访问父类的构造方法,
//对父类的数据进行初始化
//成员方法,编译看左边,运行看右边
s.show();//因为方法有重写,所以父类的方法别覆盖了
//静态方法,编译看左边,运行看左边
//静态和类相关,算不上重写
s.function();
//所以,只有成员方法,在运行时看右边,即重写了
}
}
多态的好处,提高代码的维护性(继承体现)。提高代码的扩展性(多态的体现)。
例如:
class Animal{
public 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("dog eat food");
}
public void sleep() {
System.out.println("dog sleep door");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("cat eat fish");
}
public void sleep() {
System.out.println("cat sleep box");
}
}
//修改后,加了一个动物工具,里面的方法是静态的,即可以直接用类调用
class AnimalTool{
public static void useAnimal(Animal a) {
a.eat();
a.sleep();
}
}
public class DuoTaiDemo {
public static void main(String[] args) {
Dog d=new Dog();
Cat c=new Cat();
d.eat();
d.sleep();
c.eat();
c.sleep();
//修改后,
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(c);
}
}
多态的弊端,不能使用子类的方法,对此有一下解决,即类型的转化,向上转型和向下转型
例如:
class Father{
public void show() {
System.out.println("I am a father");
}
}
class Son extends Father{
public void show() {
System.out.println("I am a son");
}
public void method() {
System.out.println("method");
}
}
public class DuoTaiDemo {
public static void main(String[] args) {
//创建一个多态
Father f=new Son();//这种定义方式是向上转型,因为new的是子类型而我们看到的是父类型
f.show();
//f.method();这个会报错,因为编译看左边,而Father类中没有method方法
//所以引出下面的解决方法,把父类的引用强制转化为子类的引用,即向下转型。
Son s=(Son)f;
s.method();
}
}
3、抽象类,把多个共性的东西提取到一个类中,这是继承的做法,但是这多个共性的东西,在有些时候方法的声明一样,但是每个具体的对象在具体实现的时候内容不一样,所以在定义这些共性的方法的时候,就不能给出具体的方法体,二没有具体的方法是抽象方法,在一个类中如果有抽象方法,该类必须定义为抽象类。
抽象类特点,抽象类和抽象方法必须使用关键字abstract修饰,抽象类不能实例化。
例如:
abstract class Animal{//抽象类的声明
public abstract void eat();//抽象类不能有方法体即不能有{}。
}
//抽象类的子类,如果是个抽象类可以直接继承父类,而如果是个具体类,则必须重写父类中的所有方法。
//abstract class Dog extends Animal{}//这是个抽象类,所有可以直接继承
//class Cat extends Animal{}这是个具体类,需要重写父类中的方法,否则会报错
abstract class Dog extends Animal{
}
class Cat extends Animal{
public void eat() {
System.out.println("I am a cat");
}
}
public class AbstractDemo {
public static void main(String[] args) {
//Animal a=new Animal();//会报错,抽象类不能实例化。抽象类中的构造方法是给子类访问父类的初始化
//可以用多态的方式对抽象类进行实例化
Animal a=new Cat();
a.eat();
}
}
//抽象类猫狗案例
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("狗吃骨头");
}
}
public class AbstractTest {
public static void main(String[] args) {
Dog d=new Dog();
d.setName("旺财");
d.setAge(3);
d.getName();
d.getAge();
d.eat();
}
}
4、接口,接口用关键字interface修饰,格式interface 接口名{}。类实现接口用implements修饰,格式class 类名 implements 接口名{}。接口不能实例化。接口是一个抽象类,是一个具体类,这个类必须重写接口中的所有接口方法。
接口的成员特点:
a:成员变量,只能是常量,并且是静态的,默认修饰符为public static final。
b:构造方法,没有构造方法。所有的类都继承Object类。
c:成员方法,只能是抽象方法,默认修饰符public和abstract。
类与类是继承关系,只能是单继承。类与接口,实现关系,可以单实现可以多实现。接口与接口,继承关系,可以单继承可以多继承。
举例:
//接口
interface AnimalTrain{
public abstract void jump();
}
//抽象类实现接口
//abstract class Dog implements AnimalTrain{}
//具体类实现接口
class Cat implements AnimalTrain{
public void jump() {
System.out.println("I am a cat");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
//AnimalTrain at=new AnimalTrain();接口是抽象的,不能实例化
AnimalTrain at=new Cat();
at.jump();
}
}
//接口猫狗案例
//定义调高接口
interface Jumpping{
public abstract void jump();
}
//定义抽象类
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();
//睡(){}
public void sleep() {
System.out.println("睡觉");
}
}
class Cat extends Animal {
public Cat() {}
public Cat(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal {
public Dog() {}
public Dog(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("狗吃肉");
}
}
//有调高功能的猫
class JumpCat extends Cat implements Jumpping{
public JumpCat() {}
public JumpCat(String name,int age) {
super(name,age);
}
public void jump() {
System.out.println("调高猫");
}
}
//有调高功能的狗
class JumpDog extends Dog implements Jumpping{
public JumpDog() {}
public JumpDog(String name,int age) {
super(name,age);
}
public void jump() {
System.out.println("调高狗");
}
}
public class InterfaceTest {
public static void main(String [] args) {
//定义调高猫
JumpCat jc=new JumpCat();
jc.setName("哆唻A梦");
jc.setAge(3);
System.out.println(jc.getName()+"---"+jc.getAge());
jc.eat();
jc.sleep();
jc.jump();
System.out.println("----------");
JumpCat jc2=new JumpCat("加菲猫",2);
jc2.eat();
jc2.sleep();
jc2.jump();
//狗的测试同上
}
}