我来跟大家分享一下今日我所学习到的java知识
1.重写
说到重写我们必然会想到重载,他们都是方法的重写或者重载 接下来我们来区分一下它们的不同
重载:
1.在同一类中
2.有多个方法,方法名相同
3.参数列表不同或者方法签名不同
重写:
1.在不同类中
2.继承或者实现
3.方法签名相同
下面的代码即为使用重写方法
例子1
public class Test{
public static void main(String[]args){
Father father =new Father();
father.words();
Son son=new Son();
son.words();
}
}
class Father{
public void words(){
system.out.println("我是你爸爸");
}
}
class Son extends Father{
public void words(){
system.out.println("我是儿子");
}
}
复制代码
大家肯定有以下问题
1.为什么我们需要用到重写呢?
需求:子类中存在父类中继承的功能,但是子类对功能的实现,与父类不一样,可以对这个功能进行方法的重写
2.如何使用重写方法:
子类对象在调用这个功能的使用,如果有重写方法,就调用重写方法,如果没有重写,就会调用从父类中继承的方法
3.如何检查是否为重写方法:
1)重写方法的左侧存在向上的三角形
2)@Override 在方法上添加注释,强制检查,如果不是重写方法就报错
注意:
1.用private修饰的,私有的内容不能被继承与重写
2.被final修饰的方法不能重写
3.static的内容不能被重写.如果子父类中存在方法签名相同的方法,父类中这个方法为static修饰的,子类中的同名方法必须也要被static修饰
2.super
说到super,我们常会把它与this进行比较,我们来比较一下它们的不同:
this
1.指代当前创建的对象
2.调用本类中的其他构造器:构造器的行首 this(参数列表)
3.区分同名的变量问题(局部和成员) this
super
1.指代父类对象
2.调用父类构造器(默认调用父类的空构造),调用父类的其他构造器需要显示使用super(参数列表),要使用在构造器的行首,this和super不能同时存在调用构造器
3.区分同名变量问题(子类和父类)
如果出现局部子类成员,父类成员同名问题,调用时候: 1)调用局部,直接写 2)调用子类成员用this 3)调用父类成员,使用super
如果不存在同名问题,相当于省略了this或者super
例子2
public class SuperDemo01 {
public static void main(String[] args) {
Fu f=new Fu();
Zi z=new Zi();
z.test("小");
}
}
class Fu{
String name="黄晓明";
public Fu(){
System.out.println("我是空构造 黄晓明");
}
public Fu(String name){
this.name=name;
System.out.println("我是带参构造 黄晓明");
}
}
class Zi extends Fu{
String name="儿子";
public Zi(){
System.out.println("我是空构造 儿子");
}
public Zi(String name){
super(name);
System.out.println("我是带参构造 儿子");
}
public void test(String name){
System.out.println(name);//小
System.out.println(this.name);//儿子
System.out.println(super.name);//黄晓明
}
}
复制代码
通过this.name我们可以直接调用本类中的属性,super.name我们可以调用父类中的属性.
final 最终的
1.被final修饰的变量为常量
变量的数据类型如果是基本数据类型:存储的数据值不能改变
变量的数据类型如果是引用数据类型:存储对象的地址不能改变,但是对象内存中的属性值可以改变
2.被final修饰的方法不能重写
3.被final修饰的类不能被继承
3.多态
多态即为一个事物可以展现不同的状态与不同的形态
多态满足的条件
1.继承:满足多态的前提要有满足继承关系的父类与子类,或者有满足实现关系的接口与子类
2.重写:继承的子类要有父类方法的重写
3.向上转型:还需要把子类的对象赋值给父类的引用,这样这个引用才有了调用父类与子类方法的能力
1.向上转型
我们常用的创建对象的方式为
Dog dog=new Dog();
复制代码
向上转型为
Animal d=new Dog();
复制代码
就是把我的子类dog的值赋值给了父类animal的引用,向上转型就是这样.
例子3
public class Demo02 {
public static void main(String[] args) {
Animal d=new Dog();
d.shout();
}
}
class Animal{
public void shout(){
System.out.println("我是动物类,会打架");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("我是小狗类,会汪汪");
}
}
复制代码
输出:我是小狗类,汪汪
这就是向上转型,父类的引用只能调用子类的重写方法
2.向下转型
向上转型之后我们不能使用子类自己的方法,这个时候我们就需要向下转型,当然使用向下转型的前提有使用向上转型.
例3中我们用到的引用d,如果先想把它转为Dog类可以这样做
Dog dog=(Dog) d;
复制代码
格式很像基本数据类型中大数据类型强转小数据类型
但我们也要注意下面的问题
public class CastDemo {
public static void main(String[] args) {
Animal d=new Dog();
Cat p=(Cat)d;
}
}
class Animal{
String name;
int age;
public void shout(){
System.out.println("我是动物");
}
}
class Dog extends Animal{
String name;
int age;
public void shout(){
System.out.println("我是小狗");
}
}
class Cat extends Animal{
String name;
int age;
public void shout(){
System.out.println("我是小猫");
}
}
复制代码
这个在编译的过程中 Cat p=(Cat)d;在编译的时候不会报错,但是我们在运行就会出现
java.lang.ClassCastException
复制代码
这个称为数据转换异常,即我们把一个Dog类转为Cat类,为了避免向下转型时出现这样的问题,我们需要使用一个关键字:instanceof
用法:
引用 instanceof 类型
复制代码
判断前面的引用是否是后面类型的一个对象|他子类对象,如果是返回true,不是返回false
if(d instanceof Cat){
Cat p=(Cat)d;
}
复制代码
这样子编译运行就不会出现错误
4.抽象类
1.定义
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.
声明抽象类的唯一目的就是将来对该类进行扩充.
2.作用
为子类提供统一规范的模板.
3.声明
格式如下:
修饰符 abstract class 类名{
成员变量;
成员方法;
抽象方法;
}
复制代码
其中抽象方法的声明格式为:
修饰符 abstract 返回值类型 方法名();
复制代码
不需要写大括号.
4.注意:
抽象类不能实例化对象,除此之外与普通类没有区别,同样具有变量,方法,构造方法.所以抽象类一定要被继承才能使用;
抽象类中可以包含非抽象方法和抽象方法;
abstract关键字不能和final,private,static一起使用.因为final的类不能被继承;private方法不能继承;static类型的方法不能被重写
5.抽象类的使用
继承抽象类必须重写抽象类中的所有抽象方法,或者声明自己为抽象
关于本文的抽象类借鉴自我的同班同桌
作者:苏红乙 链接:juejin.im/post/5db17c…