(重写,多态,final、static关键字,抽象方法,抽象类)
重写
重写前提:
- 前提是子类必须继承了父类
- 如果子类继承了父类以后,如果父类的方法满足不了我的要求,我可以在子类对父类的方法进行重写
- 重写的规则
- 子类的方法名、返回值类型必须和父类的方法名和返回类型一致
- 子类的访问修饰符不能小于父类的修饰符
- 子类和父类方法必须同为static或非static
多态
什么是多态?就是一个对象的多种形态
使用的多态的前提必须有继承或者接口的实现
1.方法的重载和重写是一种多态
2.子类对象的多态性
必须有继承
必须对父类方法进行了重写
3.程序分为两种状态,一个是编译状态,一个是运行状态
对于多态来说,编译时他看的是左边的内容,将变量看做是person类型
运行时,看右边,真正执行的对象,也就是子类对象,执行时执行的是子类重写父类的方法
public static void main(String[] args) {
//创建人类对象
Person per=new Person();
per.setName("赵四");
per.setAge(52);
System.out.println(per);//默认都会调用tostring方法
System.out.println("姓名:"+per.getName()+",年龄:"+per.getName());
per.eat();
per.sleep();
//男人类
Man man=new Man();
man.eat();
man.sleep();
System.out.println("======================");
//对象的多态性
//就是父类的引用引起子类对象
Person p1=new Man();//向上转型
//虚拟方法调用:当父类的引用指向子类对象时,实际执行的是子类重写父类的方法
p1.eat();
//通过P1可以调用子类独有的方法吗?
//在编译期间,程序会把p1看成person类型,而person中没有走路的方法
// p1.wark();
// int a=10;
// short b=(short)a;
System.out.println("=======================");
Person p2=new WoMan();
WoMan w1=(WoMan)p2;//向下转型
w1.eat();
//我就想调用子类独有的方法
w1.shopping();
System.out.println("===========================");
//为什么?因为p1已经转成男人了,把男人转成女人程序是有问题的
// WoMan w2=(WoMan)p1;
// w2.eat();
/*instanceof:格式:a instanceof 类A*/
//判断a是否是类A的实例,如果是就返回true ,如果不是就是false
if(p1 instanceof WoMan){
WoMan w2=(WoMan)p1;
w2.shopping();
}
if(p1 instanceof Man){
Man w3=(Man) p1;
w3.walk();
}
}
final
final关键字代表最终、不可改变
常见的几种用法
1.修饰类
2.修饰方法
3.修饰成员变量
4.修饰局部变量
final 关键字的用法
public final class 类名{
}
修饰类,该类有啥特点?
这个类就不能被继承,就是一个最终类(太监类)
但是可以继承别的类
使用final成员变量,成员变量的值是不可改变的
1.由于成员变量放在堆里面,那么就会有默认值,如果用final修饰成员变量,那么这个成员变量将不会再有默认值
2.如果使用了final关键字,那么要直接对成员变量进行赋值
final修饰方法,这个方法就是一个最终方法,这个方法不能被重写
final修饰局部变量
public static void main(String[] args) {
//多态
// Father fa=new Son();
// fa.show();
int num=10;
System.out.println(num);
num=20;
System.out.println(num);
//如果final修饰局部变量,那么这个变量的值是不能进行改变的
final int num1=10;
System.out.println("num1"+num1);
// num1=20;//错误的
final int num2;//正确
num2=10;
System.out.println(num2);
// num2=12;
System.out.println("==============");
//stu:保存是地址值 引用类型
Student stu=new Student("张三", 101);
stu=new Student("李四",10);
System.out.println(stu);
//引用类型变量保存的是地址值
//基本数据类型保存的变量值
final Student stu1=new Student("王五", 18);
// stu1=new Student();
stu1.setStuName("王二麻子");
System.out.println(stu1);
}
static
static:如果成员变量使用static,那么这个变量就不属于对象自己了,而是属于类本身
*
- 如果方法使用static关键字,那么这个成员方法就不属于对象自己了,而是属性类本身
- 如果没有使用static的方法,必须得先创建这个对象,然后通过【对象名.方法名】的方式进行调用
- 如果使用了static的方法,就不需要去创建对象了,而是通过【类名.方法名】的方式进行调用
- 注意:
- 静态方法中不能调用非静态的变量
- 在普通方法中可以调用静态变量吗?可以
//普通方法
public void eat(){
System.out.println("学生上课不能吃饭");
}
//静态方法
public static void sleep(){
System.out.println("学生上课不能睡觉");
}
Student.sleep();//静态方法可以直接通过【类名.方法名】的方式调用
Student stu=new Student("张三", 12, 10001, "男");
//普通方法的调用,必须得先创建对象
System.out.println("===普通方法");
stu.eat();
System.out.println("====静态方法");
stu.sleep();//不推荐
System.out.println(stu);
//如果在当前类中调用当前类的静态方法
show();
int a=10;
static int b=20;
public static void show(){
//System.out.println(a);
//错误:静态方法中不能调用非静态的变量
}
public void show1(){
System.out.println(b);
}
抽象方法
定义抽象方法:public abstract void eat();这就是一个抽象方法
- 抽象方法的特点:
- 1.只有方法的定义,没有方法体
抽象类 - 抽象类:在class前面加上abstract
- 抽象类的特点:
- 1.抽象方法所在的类必须是抽象类
- 2.抽象类不能被实例化
- 3.如果要实现抽象类,必须创建一个子类去继承抽象类
- 4.子类继承一个抽象类,必须重写抽象类中的所有抽象方法(子类也是抽象类除外)
- 5.抽象类中可以定义普通方法
- 6.抽象类可以定义构造方法
//动物 这是一个抽象类
public abstract class Animal {
private String name;//名字
//抽象方法:动物吃饭,这就是一个抽象的,因为我不知道具体是什么动物
public abstract void eat();
//睡觉方法
public abstract void sleep();
//普通方法
public void show(){
System.out.println("呵呵");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//调用吃饭方法,抽象类不能被实例化,因为动物类也是一个抽象的