Java中的继承
继承的概念
继承是一种类与类的关系,是一种“is a”的关系;
Java中的继承是单继承;
继承的好处
1.子继承父,子类只有一个父类,但是一个父类可以有多个子类;
2.子类拥有父类的属性和方法(访问看权限);
3.子类可以拥有自己的特别的属性;
4.子类可以重写父类的属性;
继承语法规则
Class 子类名 extends 父类名{
//代码块;
}
方法的重写
如果子类对父类的方法有不满意,可以重写父类继承的方法,当调用方法时会优先调用子类的方法;独特属性和继承过来的属性重名时会覆盖;
重写时返回值类型、方法名、参数的类型和个数都要与父类继承的方法相同,才叫方法的重写;
但是属性会发生覆盖,就是说即存在父类继承的同名属性又存在子类自己的重名属性;当你使用 “子类.属性”调用的是子类的重名属性,当你使用“super.属性名”调用的是父类继承的重名属性
继承的初始化顺序
1初始化父类再初始化子类;
2先执行初始化对象中的属性,再执行方法中的初始化
- 子类的构造方法永远不可能和父类的构造方法发生重名;
- 父类的构造方法负责初始化父类的属性;子类发构造方法负责初始化父类继承过来和子类自己的属性;
- 所有的构造方法第一行都存在super方法,负责调用父类的构造方法,初始化子类继承的属性;而为什么父类自己的构造方法也有super?是因为所有的类都继承object构造方法 ,可以默认不写而已;
- 如果我们不手动写构造方法 系统会生成无参构造方法 如果你手动写了系统就不会自动生成了
权限修饰符
protected 继承中访问范围放大可以跨包访问;
而default 不变
java中的抽象类
抽象类使用abstract关键字修饰,则该类为抽象类。
应用场景
- 在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但是无法准确知道这些子类如何实现这些方法;
- 从多个具有相同特征的累中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性;
- 抽象类是一类有共同点的事物模型,抽象方法也一样,当被继承时才有具体的意义。抽象类是用来继承的,继承的子类一定要重写抽象方法
作用
限制规定子类必须实现某些方法,但是不关注细节;
使用规则
- abstract定义抽象类;
- abstract定义抽象方法,只有声明,不需要实现;
- 包含抽象方法的类是抽象类;
- 抽象类不能创建对象;但是可以有构造方法,方便子类初始化继承过来属性;
- 抽象方法只存在于接口和抽象类中,抽象类中可以含有非抽象方法
抽象语法规则
public abstract 返回值类型 方法名();
例子 :有一个shape的抽象类,拥有周长和面积的;定义一个子类也拥有自己的周长和面积;
抽象类:
package abstractt;
public abstract class shape { //抽象类的定义
public int y; //普通属性
public abstract void size(); //抽象方法定义
public abstract void man();
}
子类:
package abstractt;
public class rectangle extends shape { //继承
@Override
public void size() { //重写方法
// TODO Auto-generated method stub
System.out.println("圆的周长" + y);
}
@Override
public void man() {
// TODO Auto-generated method stub
System.out.println("圆的面积");
}
}
测试类:
package abstractt;
public class intlie {
public static void main(String[] args) {
rectangle rec = new rectangle();
rec.y = 1;
rec.size();
rec.man();
}
}
子类继承到的抽象类的父类时,每个子类对象所继承到的父类的属性为非公有的,即每个子类对象都有自己继承复制到的父类属性;跟没有static修饰的普通继承一样; 其实说的是static修饰的属性为公共属性而已;
抽象父类:
package abstractt;
public abstract class Car {
public int y;
protected Car(int y) { //父类的构造方法
super();
this.y = y;
}
public abstract void YunShu(); //抽象方法
public abstract void ZaiKe();
}
子类:
package abstractt;
public class MianBaoCar extends Car {
public int yy;
protected MianBaoCar(int y, int yy) { //子类的全参构造方法
super(y);
this.yy = yy;
}
@Override
public void YunShu() {
System.out.println("我每小时跑40公里!");
}
@Override
public void ZaiKe() {
System.out.println("我可以运输8个人");
}
public int j() { //间接调用super的属性
return super.y;
}
}
测试类:
package abstractt;
public class intlie {
public static void main(String[] args) {
MianBaoCar red = new MianBaoCar(11, 11);
System.out.println("red.super.j " + red.j());
red.YunShu();
red.ZaiKe();
MianBaoCar blue = new MianBaoCar(22,22);
System.out.println("blue.super,j " + blue.j());
System.out.println("red.super.j " + red.j());
}
}
结果:
java中的接口interface
接口属性:
- 接口中的属性都是常量(常量一般全大写),方法都是抽象方法;
- 都用public修饰:
public static final int i=1;简写成nt i;
默认都是常量,一旦赋值无法修改;
public abstract void f();简写成viod f();
- 接口中不存在构造方法;(接口中的属性一经定义赋值就无法修改,所以不需要构造方法来初始化继承的接口的属性);
抽象类和接口的区别和相同点:
相同: 都可以有抽象方法(抽象类中可以存在非抽象方法,当时接口中一定是抽象方法);
不同:
1抽象类是继承,接口是实现;(一个子类只能拥有一个父类,但是可以拥有多个接口);
2接口没有构造方法;