final
格式
final class 类名 {}
final 数据类型 变量名
public final 数据类型 方法名(){}
final的特点:
final:最终的的意思。它可以修饰类,成员变量,成员方法
特点:
1、修饰类,类不能被继承
2、修饰成员变量,变量变常量,并且只能赋值一次,在构造方法完毕之前赋值即可。
常量:
字面值常量
自定义常量:被final修饰变量变成自定义常量
3、final修饰成员方法:方法不能被重写
final修饰局部变量
1、在方法内部,修饰基本数据类型的变量,变量值只能赋值一次,不能发生改变
2、修饰引用数据类型的变量,引用的地址值不可以发生改变你,但是该对象的堆内存中的值是可以发生改变的。
多态
多态的前提:(三个缺一不可)
1、要有继承关系
2、要有方法的重写。
3、要有父类的引用指向子类对象
父类名 f = new 子类名(...); 注:可以隔代多态
多态访问成员的特点:
1、成员变量
编译看左,运行看左
2、构造方法
创建子类对象的时候,先访问父类中的构造方法,对父类的数据先进行初始化
3、成员方法
编译看左,运行看右。
因为成员方法存在重写,所以访问看右边
4、静态成员方法
编译看左,运行也看左。
由于被static修饰的成员都是与类相关的,这里不是重写,所以运行的时候,访问的还是左边的。
package com.shujia.wyh.day11;
class Fu3{
int num = 100;
public void show(){
System.out.println("这是父类中show()方法");
}
public static void fun(){
System.out.println("这是父类中的静态fun方法");
}
}
class Zi3 extends Fu3{
int num = 1000;
@Override
public void show(){
System.out.println("这是子类中的show()方法");
}
public void show2(){
System.out.println("这是子类特有的方法1");
}
public static void fun(){
System.out.println("这是子类中的静态fun方法");
}
}
public class PolymorphicDemo1 {
public static void main(String[] args) {
//多态创建了一个对象
Fu3 f = new Zi3();
System.out.println(f.num);//100//编译看左,运行看左
f.show(); // 这是子类中的show()方法//编译看左,运行看右
f.fun();//这是父类中的静态fun方法//编译看左,运行也看左
}
}
多态的好处:1、提高了程序的维护性(由继承保证)2、 提高了程序的扩展性(由多态保证)
多态的弊端:1、多态无法访问父类中的方法名一样的方法2、不能访问子类特有的方法
解决方法:
1、想使用父类中的方法,就不使用多态
2、如果我想使用子类中的特有方法,还必须使用多态,就要向下转型
向下转型:将父类的引用强制转换成子类的引用
子类类名 变量名 = (子类类名)父类的引用;
对象之间转型的问题:
1、向上转型:
Fu f = new Son();
2、向下转型
Son s = (Son)f;
向下转型需要注意的一个问题:
要求转型的类与父类引用存在继承关系,并且一开始多态创建对象的时候,使用的是该类。
package com.shujia.wyh.day11;
class Father2{
public void show(){
System.out.println("这是父类中的show方法");
}
}
class Son2 extends Father2{
@Override
public void show() {
System.out.println("这是子类中的show方法");
}
public void show2(){
System.out.println("这是子类中特有的方法");
}
}
class Demo extends Father2{}
public class PolymorphicDemo3 {
public static void main(String[] args) {
// 多态创建对象
Father2 f = new Son2();
// f.show2();
// 将父类的引用进行向下转型
// 子类类名 变量名 = (子类类名)父类的引用;
Son2 s = (Son2)f;
s.show2();
s.show();
Demo d = (Demo)f;
d.show(); //多态创建对象的时候,使用的不是该类
}
}
抽象类(abstract关键字)
抽象类特点
1、 抽象类和抽象方法必须用abstract关键字修饰
格式
abstract class 类名 {}
public abstract void eat(); 没有方法体{},连大括号都没有,直接以分号结尾
2、抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
3、抽象类不能实例化
那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
4、抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
package com.shujia.wyh.day11;
//定义了一个抽象类,叫Animal3
abstract class Animal3{
//注意:
//抽象方法没有方法体{},连大括号都没有,直接以分号结尾
// public abstract void eat(){};
public abstract void eat();
public abstract void drink();
}
class Dog3 extends Animal3{
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public void drink() {
System.out.println("狗喝水");
}
}
public class AbstractDemo1 {
public static void main(String[] args) {
//利用具体子类多态形式创建对象
//抽象多态的形式
Animal3 a = new Dog3();
a.eat();
a.drink();
}
}
抽象类的成员的特点:
成员变量:
既可以是变量,也可以是常量
构造方法:
在继承中要想初始化子类,必须先初始化父类,所以这里构造方法是提供初始化父类的作用
成员方法:
可以是抽象方法,但是具体的子类必须要重写该方法
也可以不是抽象方法,提高代码的复用性。
抽象类中可以存在哪些关键字?public
abstract关键字不能和哪些关键字共存?
private
static
final