继承和多态
继承
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
public class 子类名 extends 父类
特点:子类可以有父类的内容;子类还可以有自己特有的内容
继承的访问特点:在子类方法中访问一个变量可以在①子类局部范围找;② 子类成员范围找;③ 父类成员范围找;④ 如果没有就会报错
super关键字
super关键字与this关键字的用法相似:this代表本类对象的引用;super代表父类存储空间的标记,即为父类对象的引用。
this
super
this.成员变量
super.成员变量
访问本类成员变量
访问父类成员变量
this(…)
super(…)
访问本类构造方法
访问父类构造方法
this.成员方法(…)
super.成员方法(…)
访问本类成员方法
访问父类成员方法
实例:
Fu.java
public class Fu{
public int age = 40;
}
Zi.java
public class Zi extends Fu {
// public int age = 20;
public void show(){
// int age=30;
System.out.println(age);
}
}
demo.java
public class demo {
public static void main(String[] args){
Zi z = new Zi();
z.show();
}
}
·继承中构造方法的访问特点
子类中所有的构造方法默认都会访问父类中无参的构造方法:因为子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化;每一个子类构造方法的第一条语句默认都是super()。
若父类中没有无参构造方法,只有带参构造方法:通过使用super关键字去显示的调用父类的带参构造方法;在父类中自己提供一个无参构造方法
·通过子类对象访问一个方法:子类成员范围找;父类成员范围找;若都没有则报错
Fu.java
public class Fu {
public void show() {
System.out.println("Fu中show方法被调用");
}
}
Zi.java
public class Zi extends Fu {
public void method(){
System.out.println("Zi中method方法被调用");
}
public void show(){
// 访问的是父类中的方法
super.show();
System.out.println("Zi中show方法被调用");
}
}
demo.java
public class demo {
public static void main(String[] args){
// 创建对象
Zi z = new Zi();
z.method();
z.show();
}
}
Zi中method方法被调用
Fu中show方法被调用
Zi中show方法被调用
方法重写
子类中出现了和父类中一模一样的方法声明;
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
Fu.java
public class Fu {
public void call(String name) {
System.out.println("给"+name+"打电话");
}
}
Zi.java
public class Zi extends Fu {
// 方法重写
public void call(String name) {
System.out.println("开启视频功能");
// 直接在子类中定义
// System.out.println("给"+name+"打电话");
// 调用父类的功能
super.call("严浩翔");
}
}
demo.java
public class demo {
public static void main(String[] args){
// 创建对象
Fu p = new Fu();
p.call("严浩翔");
System.out.println("--------");
Zi np = new Zi();
np.call("严浩翔");
}
}
给严浩翔打电话
--------
开启视频功能
给严浩翔打电话
注意:私有方法不能被重写父类私有成员子类是不能继承的;子类方法访问权限不能更低public>默认>私有;java中类只支持单继承,不支持多继承;支持多层继承
_package
其实就是文件夹,对类进行分类管理package 包名
package语句必须放在源文件开头;一个源文件只能有一个package语句;包名字全部小写,避免与类、接口的名字冲突。
编译带包的类javac -d 目录 源文件名.java
运行带包的类java 包名.类名
import
导包import 包名
修饰符有:
private 只在同一个类中可以被访问
默认 在同一个类中可以被访问,同一个包中子类无关类
protected 同一个类中,同一个包中子类无关类,不同包的子类,不同包的无关类
public 同一个类中,同一个包中子类无关类,不同包的子类,不同包的无关类
final
是最终的意思,可以修饰成员的方法,成员变量,类
特点:
修饰方法,表明该方法是最终方法,不能被重写
修饰变量,表明该变量是常量,不能再次被赋值
修饰类,表明该类是最终类,不能被继承
final修饰局部变量
① 变量是基本类型:final修饰指的是基本类型的数据值不能发生改变;
② 变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的;
static
是静态的意思,可以修饰成员方法,成员变量。
static 修饰的特点:① 被类的所有对象共享(这也是我们判断是否使用静态关键字的条件)② 可以通过类名调用
Fu.java
public class Fu {
// 非静态成员变量
public String name;
// 静态成员变量
public static int age;
public void show(){
System.out.println(name+' '+age);
}
}
demo.java
public class demo {
public static void main(String[] args) {
// 创建对象
Fu.age=18;
Fu s1 = new Fu();
s1.name="严浩翔";
// s1.age=18;
s1.show();
Fu s2 = new Fu();
s2.name="太上老君";
// s2.age=18;
s2.show();
}
}
注意:静态成员方法只能访问静态成员变量
多态
格式:父类 name = new 子类
实现多态有三个条件:继承、重写、向上转型,即相同的消息使得不同的类做出不同的响应。
抽象类
在java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象方法。
// 抽象类
public abstract class animal{
// 抽象方法
public abstract void eat();
}
抽象类的特点:
① 抽象类和抽象方法必须使用abstract关键字修饰public abstract class 类名()
,public abstract void eat()
② 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
③ 抽象类不能实例化,需要通过子类对象实例化,这叫做抽象类多态
④ 抽象类的子类:要么重写抽象类中的所有的抽象方法;要么是抽象类
抽象类的成员变量特点:
① 成员变量:可以是变量;也可以是常量
② 构造方法:有构造方法,但是不能实例化,要通过子类访问父类数据的初始化
③ 成员方法:可以有抽象方法,确定子类必须完成某些动作;也可以有非抽象方法,提高代码的复用性
例如:
(父类)aniaml.java
// 抽象类
public abstract class animal{
private int age=20;
private final String city="天津";
// 无参方法
public animal(){}
// 有参方法
public animal(int age){
this.age=age;
}
// 定义非抽象方法
public void show(){
// age=23;
System.out.println(age);
System.out.println(city);
}
// 限定子类必须要去重写抽象类的方法
public abstract void eat();
}
(子类)cat.java
public class cat extends animal{
// 重写父类中的方法
@Override
public void eat(){
System.out.println("吃鱼");
}
}
(测试类)demo.java
public class demo {
public static void main(String[] args) {
// 多态
animal a = new cat();
a.eat();
a.show();
}
}