今天继续分享一些关于java中的知识点,说的不好还请多多指正,谢谢.
1.重写
昨天我们知道继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为.
但是如果子类继承的父类方法不满足自己的需求呢?
这个时候就可以使用重写.
-
定义 重写是子类对父类允许访问的方法的实现过程进行重新编写.方法名,返回值和形参都不能改变.即外壳不变,核心重写.
-
重写规则 :
- 重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常;
- final修饰的方法可以被继承但是不可被重写;
- 重写的方法不能比父类中被重写的方法的访问权限更低;
- 声明的static方法不能重写.
注意:只有方法才有重写定义,变量没有
示例1:
class Animal{
String name;
public void shout(){
System.out.println(" ");
}
}
class Dog extends Animal{
String name;
public void shout(){
System.out.println("汪汪汪");
}
}
上面的子类中的shout方法就重写了继承的方法.
2.super
在继承中,有个super关键字.super关键字有两个用处:
1.调用父类的构造方法
调用语法格式:
super([参数列表]);
注意:
- 使用super调用父类的构造方法时,super语句必须是子类构造方法的第一条语句;
- 调用父类构造方法的唯一途径是使用super关键字
- 如果子类中没有显式调用,子类会自动将super();作为子类构造方法中的第一条语句;
- 静态方法中不能使用super关键字
- this与super不同时存在调用构造方法使用.
2.调用父类的成员
调用成员方法语法格式:
super.方法名();
这种情况主要发生在子类重写了该方法,需要调用父类中的这个方法时使用.
调用成员变量语法格式:
super.变量名;
这种情况发生在子类中有与父类中同名的变量.
创建子类对象之前,是先创建父类对象的
3.多态
多态,简言之就是一件事物可以表现为不同的形式或有不同的形态.
1.首先看满足多态的条件:
- 继承:满足多态的前提就必须要有满足继承关系的父类和子类,亦或有满足实现关系的接口与子类
- 重写:继承的子类中必须要有对父类方法的重写
- 向上转型:还需要把子类的对象赋值给父类型的引用,这样这个引用才有调用父类方法和子类方法的能力.
2.向上转型
平时我们创建一个新的对象的做法为:
Student stu=new Student();
把一个Student对象赋值给了一个Student型的引用.而向上转型就是把一个子类的对象赋值给父类类型的引用,也就是把这个对象转换成了父类类型.例如:
示例2:
public class CastDemo {
public static void main(String[] args) {
Person1 p = new Teacher();
p.work();
}
}
class Person1 {
String name;
int age;
public void work() {
System.out.println("平常工作");
}
}
class Teacher extends Person1 {
String name;
int age;
public void work() {
System.out.println("讲课");
}
public void teach(){
System.out.println("教书育人");
}
}
输出:讲课
这就是向上转型
注意,转型之后父类类型引用是调用不了子类中自己扩展的方法的,只能调用子类中重写的方法.
3.向下转型
向上转型之后,就用不了子类自己的方法了,但如果就是要用呢?我们这个时候可以使用向下转型.注意,向下转型之前必须要有向上转型.
如示例2向上转型之后的引用p,如果我们想把它转为Teacher类型,可以这样做:
Teacher t=(Teacher)p;
格式有点像基本数据类型中大的数据类型强转为小数据类型
但是这个时候我们需要注意这种情况:
示例3:
public class CastDemo {
public static void main(String[] args) {
Person1 p = new Teacher();
p.work();
}
}
class Person1 {
String name;
int age;
public void work() {
System.out.println("平常工作");
}
}
class Teacher extends Person1 {
String name;
int age;
public void work() {
System.out.println("讲课");
}
}
class Doctor extends Person1{
String name;
int age;
public void work() {
System.out.println("治病救人");
}
}
这个时候,当我们向下转型这样写:
Doctor d=(Doctor)p;
这样编译是没问题的,但是我们运行程序时就会出现java.lang.ClassCastException这个异常,称为数据转换异常.也就是说我们把一个Teacher转为一个Doctor.
为了避免在向下转型时遇到这种情况,需要一个关键字:instanceof
用法:
引用 instanceof 类型
判断前面的引用是否是后面类型的一个对象|他子类对象,如果是返回true,不是返回false
例如我们在向下转型时这样:
if(p instanceof Doctor){
Doctor d=(Doctor)p;
}
这样就不会出现编译没错,但是运行出错的情况.
4.有多态时的成员访问特点
- 成员变量:编译运行看左边|父类(就是有多态时,访问成员变量不管是编译还是运行都是根据父类)
- 成员方法:编译看左|父类,运行看右|子类(在编译时,先看父类中是否有这个方法,没有则报错,有的话运行时看子类中是否有,如果有就调用子类中的,没有就调用父类中的)
- 静态方法:编译运行看左边|父类
4.抽象类
1.定义
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.
声明抽象类的唯一目的就是将来对该类进行扩充.
2.作用
为子类提供统一规范的模板.
3.声明
格式如下:
修饰符 abstract class 类名{
成员变量;
成员方法;
抽象方法;
}
其中抽象方法的声明格式为:
修饰符 abstract 返回值类型 方法名();
不需要写大括号.
4.注意:
- 抽象类不能实例化对象,除此之外与普通类没有区别,同样具有变量,方法,构造方法.所以抽象类一定要被继承才能使用;
- 抽象类中可以包含非抽象方法和抽象方法;
- abstract关键字不能和final,private,static一起使用.因为final的类不能被继承;private方法不能继承;static类型的方法不能被重写
5.抽象类的使用
继承抽象类必须重写抽象类中的所有抽象方法,或者声明自己为抽象类.