笔记整理-Java基础03(继承、抽象类、接口、多态、final关键字、权限修饰符、匿名内部类)

前言:

感觉看自己过去的笔记,一不方便二感觉不完善,所以把自己以前的笔记整理在CSDN上,不足之处还请指正。

java开发学习笔记整理导航


继承

概念:
当多个类中具有相同的成员变量和成员方法时,把这些相同的成员抽取出来,放到另一个类中,当某个类需要这些成员时,就不需要再写一遍直接继承该类即可

注意:java中只支持单继承,不支持多继承,支持多层继承

定义:
继承是描述两个类之间的关系
类A继承了类B,那么类A会自动拥有类B中非私有的成员,这个过程就是继承
类A称为子类、类B称为父类

继承的格式

public class 父类{
	//共有成员
}
public class 子类1 extends 父类{
	//子类可以添加自己特有的成员
}
public class 子类2 extends 父类{
	//子类可以添加自己特有的成员
}

继承的好处

提高了代码的可复用性
给多态做了前提

继承的特点(super的作用)

1.继承后成员变量的特点
父子类中的成员变量不同名是不会有任何问题,若同名会根据就近原则,在子类中优先访问子类自己的成员变量

这里要说一下this、super关键字区分变量的不同
this:用来区分本类中成员变量和局部变量的同名情况
super:用来区分子类的成员变量和父类的成员变量同名的情况

但在开发中是不会是父子类的成员变量同名的!所以了解即可

2.继承后成员方法的特点
如果父子类的成员方法不同名,是不会出现任何问题的
如果父子类的成员方法同名了,根据就近原则在子类中优先调用子类自己的方法,在子类的方法中,可以使用【super.方法名()】指定调用父类继承而来的方法

3.继承后构造方法的特点
在说构造方法继承的情况前,先了解下构造方法自身的特点
不写任何返回值,void也不写
方法名必须和类名保持一致
由于构造方法的特殊性,所以构造方法不存在继承

方法的重写

什么是重写:
在子类中出现了和父类一摸一样的方法(方法的声明)那么子类中的方法被称为重写的方法

重写的应用
当子类继承了父类的方法但是发现某些方法的功能比较low时那么子类可以重写此方法
在实际开发中会继承jdk中的类重写某个不满意的方法

注意:
子类方法重写父类方法,必须要保证权限大于或等于父类权限
如果父类的方法是私有的就没有重写私有方法的这种说法,因为私有方法不能继承

this、super总结(访问变量、调用方法)

在子类中访问变量
this.成员变量名;
访问子类自己的成员变量,如果子类不存在该成员变量,也会访问父类继承而来的成员变量
super.成员变量名;
直接访问父类继承而来的成员变量
这里的成员变量是什么?
优先局部变量,再去子类的成员变量,再去父类继承而来的成员变量

在子类中调用方法
this.成员方法名();
调用子类自己的成员方法,如果子类没有该方法,也会调用父类继承而来的成员方法
super.成员方法名();
直接调用父类继承而来的成员方法

所以只是单单是 成员方法名(); ==> 等价于 this.成员方法名();

扩展:this和super访问构造

this(参数):
调用本类的其他构造,具体是哪一个构造,由参数列表决定
super(参数): 调用父类的构造

子类的所有构造,默认第一行都会有一句代码,super(),调用父类的无参构造
因为Java设计之初遵循了一个原则: 单一职责

父类继承过来的成员变量,由父类的构造进行初始化
子类自己的成员变量,由子类的构造进行初始化


抽象类

由来:
一个父类有多个子类,所有子类都重写某个方法,那么父类中的这个方法存在的价值就不高了
于是java提出了一个新的方法:抽象方法(抽象方法所在的类必须是抽象类)

抽象类概念:
只要该类是 abstract 修饰的,那么这个类就是抽象类
抽象类可以有抽象方法,也可以没有抽象方法

抽象类定义格式

public abstract class 类名{
	//可以有抽象方法也可以没有
}

抽象类使用
不能创建对象,java规定天生做父类,被子类继承的
其他子类继承抽象类后,必须重写抽象类中所有的抽象方法,才能创建对象否则子类还是抽象类

抽象方法

概念:只有方法的声明(方法的头部),没有方法的实现(没有实现体),并加上 abstract 修饰

抽象方法定义格式

public abstract 返回值类型 方法名(参数列表);

抽象类总结

抽象类存在的意义: 是作为父类
抽象方法存在的意义: 强制子类必须重写
抽象类不能创建对象
抽象类中,可以有构造方法
抽象类中,不一定包含抽象方法
抽象类的子类,必须重写抽象父类中所有的抽象方法


接口

说接口前再说一下java中的数据类型
基本数据类型:四类八种
引用数据类型:数组、类、接口

什么是接口:
接口就是方法的集合,接口中只允许定义方法,不允许定义成员变量(但可以定义常量),没有构造方法不能创建对象,没有静态代码块
定义常量:

public static final 数据类型 常量名 =;

接口中定义的方法
1.接口中不能定义普通的成员方法
2.抽象方法
3.静态方法
4.私有方法

接口定义的格式

接口定义 interface
格式,会有以下的方法

public interface 接口名{
	public abstract void 方法名();//抽象方法,常用
	public default void 方法名(){...}//默认方法
	public static void 方法名(){...}//静态方法
	private void 方法名(){...}//私有方法
	private static void 方法名(){...}//私有方法
} 

接口的使用

接口不能创建对象,接口是没有构造方法,接口天生做父类,实现可以理解为继承
实现类实现(implements)父接口
实现类可以拥有父类中的非私有成员

实现类必须重写父接口中的所有抽象方法
可以选择性重写默认方法
静态方法没有继承说法,因为静态方法只能通过所在的接口名直接调用
私有方法是不能被继承的

接口的多实现
java中类实现接口可以多实现
格式:

public class 实现类 implements 接口1,接口2...{
	//必须重写所有接口中的所有抽象方法,如果接口中有相同的抽象方法,那么实现类只需要重写一次即可
	//选择性重写默认方法,如果接口中有相同的默认方法那么实现类必须重写一次
	//静态方法和私有方法无影响
}

继承和实现的优先级问题

一个类可以继承一个父类同时可以实现多个接口
格式:

public class 子类/实现类 extends 父类 implements 接口1,接口2..{
	//重写父类和所有接口中的所有抽象方法,若有些抽象方法是相同的只需要重写一次
	//如果父类的非抽象方法和接口中的默认方法一致,实现类不需要重写,优先调用父类中的非抽象方法
}

接口的多继承

类与类是继承,单继承
类与接口是实现,多实现
接口与接口是继承,多继承

格式:

public interface 子接口 extends 父接口1,父接口2 ...{
	//自动拥有所有父接口中的所有非私有方法
	//如果父接口有相同的默认方法,那么子接口必须重写一次默认方法
}

多态

字面意思理解什么时多态,就是一种事物的多种形态

多态的前提与体现

多态必须满足两个前提
1.必须有继承关系或者实现关系
2.必须有方法的重写(没有重写的多态是没有意义的)
多态的体现
父类类型的变量 指向了 子类类型的对象

父类 变量名 = new 子类();

多态代码的体现

1.直接多态

Animal an1 = new Dog();
Dog an2 = new BigYellowDog();
Animal an3 = new BigYellowDog();

2.调用方法时参数的多态

//定义方法
public static void test(Animal an) {
}
//调用方法
Dog wangcai = new Dog();
test(wangcai);//wangcai是Dog类,将Dog类作为参数传给test方法,但是形参是Animal类,故为 Animal an = new Dog();

3.调用方法时返回值的多态

//定义方法
public static Animal getAnimal() {
	BigYellowDog byd = new BigYellowDog();
    return byd;
}
//调用方法
Animal an4 = getAnimal();//相当于返回 new BigYellowDog();

多态调用方法的特点

多态调用方法时,编译看父类,运行看子类
所以多态只能运行子父类共有的方法

多态的好处

多态提高程序的扩展性

public abstract class Animal {
    public abstract void eat();
}

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗说:这肉骨头真好吃...");
    }
}

public class Tiger extends Animal{
    @Override
    public void eat() {
        System.out.println("老虎说:这人真好吃...");
    }
}

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫说:这鱼骨头真好吃..");
    }
}

public class Pig extends Animal {
    @Override
    public void eat() {
        System.out.println("猪说:这啥玩意,真好吃...");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //调用喂猫方法
        Cat jf = new Cat();
        feedAnimal(jf);
        //调用喂狗吃饭
        Dog wangcai = new Dog();
        feedAnimal(wangcai);
        //调用喂猪吃饭
        Pig pq = new Pig();
        feedAnimal(pq);
        //调用喂老虎吃饭
        Tiger dbhu = new Tiger();
        feedAnimal(dbhu);

    }
    //定义方法:喂动物吃饭
    public static void feedAnimal(Animal an) {
        System.out.println("小宝贝,开饭了....");
        an.eat();
    }
}

运行结果截图
笔记整理-Java基础03(继承、抽象类、接口、多态、final关键字、权限修饰符、匿名内部类)_第1张图片

多态的弊端

多态只能运行子父类共有方法,不能运行子类独有方法

多态弊端的解决方案–转型

了解向上转型,也就是自动转型
子类类型可以转成父类类型

Animal an = new Dog();//多态
double d = 10;//自动类型转换

向下转型,也就是强制类型转换
父类类型转回子类类型

Animal an = new Dog();//多态
Dog wangcai = (Dog)an;//多态
int i = (int)3.0;//强制转换

多态转型过程可能出现问题

编译器在 父类类型 向下转型为 子类类型时,不会检查具体的子类是否正确
但是运行时,会直接程序崩溃

instanceof关键字的介绍

本质是一个运算符

使用格式:

对象名 instanceof 类型

作用:判断左边的对象是不是右边类型的对象
结果:布尔类型
因为要先使用 instanceof 计算后,才能转型


final关键字

作用:用于修饰

修饰类

该类不能被继承,好比是“太监”类
格式:

public final class 类名{...}

修饰方法

该方法不能被重写,好比这个方法是最万能的不需要重写
格式:

public final 返回值类型 方法名(参数列表){
}

修饰局部变量

该局部变量只能赋值一次(常量)
1.定义时直接赋值
2.先定义后赋值

public static void main(String[] args){
	final int a = 10;
	a = 20;//报错
	//或者
	final int b;
	b = 10;
	b = 20;//报错
}

修饰成员变量

该成员变量只能赋值一次
1.定义成员变量时直接赋值
2.定义成员变量时,不赋值,在构造方法中给其赋值
格式:

public class 类名{
	//成员变量
	final int age = 10;
	//成员变量
	final int a;
	public 类名(){
	this.a = 10;
	}
}

修饰引用类型的变量

该对象保存的地址不能改变,因为指向对象就不能改了,但是对象中的成员变量值可以改变的(除非该成员变量也由final修饰)
格式:

final 类名 对象名 = new 类名();

权限修饰符

java中的四种权限修饰符
从小到大
public: 公共修饰符,任何包任何类都可以使用
protected: 受保护修饰符,同包的其他类,或者 不同包的子类中可以使用
不写(default): 默认修饰符, 只能在同包的类中使用
private: 私有修饰符,只能在本类中使用
笔记整理-Java基础03(继承、抽象类、接口、多态、final关键字、权限修饰符、匿名内部类)_第2张图片


匿名内部类

先了解内部类
一个类A 定义在了另外一个类B的内部:
类A被称为内部类,类B一般称为外部类
根据内部类的定义位置:
1.类中方法外: 成员内部类
2.类中方法中: 局部内部类

成员内部类

内部类定义在了成员位置,称为成员内部类
特点:
成员内部类中可以无条件访问外部类的一切成员
格式:

外部类名.内部类名 对象名 = new 外部类().new 内部类();

[重点]匿名内部类

语法糖:用来创建抽象类的子类和接口的实现类对象的语法糖

创建抽象类的子类对象:

抽象类 对象名 = new 抽象类(){
	//子类必须重写抽象类中所有的抽象方法
};

创建接口的实现类对象:

接口名 对象名 = new 接口(){
	//实现类必须重写接口中所有的抽象方法
};

以后会不定期,将自己学习的Java技术整理出来。错误之处还请指出。
祝大家头发多多,bug少少。

你可能感兴趣的:(javase)