继承是(抽象,封装)是面向对像的三大特征之一,继承可以使子类具有父类的属性和方法,还可以在子类中重新定义、追加属性和方法。
1、继承的格式:
public class 子类名 extends 父类名{}
public class zi extends fu{}
父类被称为基类或者超类
子类也被称为派生类
下面通过代码创建父类,子类继承父类,测试代码...
父类;
package extend;
public class fu {
public void show(){
System.out.println("我是父类show 方法");
}
//未提供构造方法,默认有一个无参构造方法
}
子类:
package extend;
public class zi extends fu{
public void show1(){
System.out.println("子类show 方法");
}
}
测试代码:
package extend;
public class test {
public static void main(String[] args){
//如果要调用fu类中的方法,就得创建父类对象
//这里用无参构造方法创建对象
fu f=new fu();
f.show();
//同理调用子类中的方法
zi z=new zi();
z.show1();
//子调用父类中的show方法
zi z_extend=new zi();
z_extend.show();
}
}
总结:
子类可以调用父类的内容,
子类可以有自己特有的内容
继承的优点:
提高了代码复用性(多个类相同的成员可以放到同一个类中)
提高了代码的维护性(如果方法代码需要修改,则修改一处(放在父类中,修改父类的方法 )即可)
继承的弊端:
继承让类和子类之间产生了关系,类的耦合性增强了,当父类发生变化,子类也不得不发生变化,削弱了子类独立性
什么时候使用继承
is a 方法
现有两个类,A和B,若他们满足:A是B的一种,或者B是A的一种,说明他们存在继承关系,可以使用继承。
例子: 水果和苹果 动物和猫 这俩都行,但是 苹果和香蕉 就不行
继承变量访问特点:访问顺序:
子类方法的局部范围内,子类成员范围内,父类成员范围内
2、Super关键字的使用
父类:
package fuzi;
public class Fu {
int age=50;
}
子类:
package fuzi;
public class Zi extends Fu{
public int age=40;
public void show(){
int age=30;
//访问的是方法的变量
System.out.println(age);
//访问本类成员变量
System.out.println(this.age);
//访问父类成员变量
System.out.println(super.age);
}
}
测试代码:
package fuzi;
public class exteend {
public static void main(String[] args){
Zi z=new Zi();
z.show();
}
}
//输出:
30
40
50
supper使用方法总结:
3、继承中构造方法访问特点
先写代码:fu类:
package fuzi;
public class Fu {
public Fu(){
System.out.println("Fu类中无参构造");
}
public Fu(int age){
System.out.println("Fu类代餐构造方法");
}
}
zi类:
package fuzi;
public class Zi extends Fu{
public Zi(){
System.out.println("zi类无参构造方法");
}
public Zi(int age){
System.out.println("zi类代餐构造方法");
}
}
测试代码:
package fuzi;
public class exteend {
public static void main(String[] args){
//用无参构造方法创建对象
Zi z1=new Zi();
//用代餐构造方法创建对象
Zi z2=new Zi(21);
}
}
输出结果:
这里我们发现:
当我们使用无参构造方法创建对象,父类中的无参构造方法首先得到调用,之后再调用子类中的无参构造方法;
但是,如果我们使用带参构造方法创建对象,首先调用的却是父类的无参构造方法,子类调用带参构造方法。
原因:
因为子类会继承父类的数据,可能还会使用父类的数据,因此在子类初始化之前一定要先完成父类的初始化;并且每个子类构造方法的第一条初始语句一定是super();(一般默认存在,不用自己写)
如果我们不写父类无参构造方法,子类中会报错,此时我们就需要人为的安排子类通过父类的带参构造方法初始化数据
代码如下:
package fuzi;
public class Zi extends Fu{
public Zi(){
super(10);
System.out.println("zi类无参构造方法");
}
public Zi(int age){
super(10);
System.out.println("zi类代餐构造方法");
}
}
如果我们就是不想调用父类的带参造方法,但是父类中又没有,那我们可以自己在父类中定义一个无参构造方法:
public Fu(){} 这样不用在子类中使用super
4、继承中成员方法的访问特点:
先展示代码:父类
package fuzi;
public class Fu {
public void show(){
System.out.println("Fu类中的show方法");
}
}
子类代码:
package fuzi;
public class Zi extends Fu{
public void methond(){
System.out.println("zi类中methond方法");
}
public void show(){
System.out.println("zi 中show方法");
}
}
测试代码:
package fuzi;
public class exteend {
public static void main(String[] args) {
//用无参构造方法创建对象
Zi z1 = new Zi();
z1.methond();
//子类继承了fu中的show方法,因此可以直接调用,
//但是如果子类中有与父中同名的方法,那么子类会覆盖fu中的方法
z1.show();
}
}
此时如果我们想在zi类中已经拥有与fu同名的方法,那我们该如何实现调用fu中的同名方法呢?
解决方法:在子类同名方法的第一行添加代码:super();
5、方法重写
1、重写概述:
子类出现了和父类一模一样的声明
2、应用场景:
子类需要父亲的功能,而该功能的主体子类又有自己的特殊内容时,这样可以重写父类中的方法,这样既沿袭了父类的功能,又有子类自己的特有内容。
代码演示:
父类:
package Call;
public class Phone {
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
子类:
package Call;
public class newphone extends Phone {
//@Override表示重写方法,
@Override
public void call(String name){
System.out.println("开启视频");
super.call("神里");
}
}
测试类:
package Call;
public class test {
public static void main(String[] args) {
Phone p=new Phone();
p.call("可莉");
newphone p1=new newphone();
p1.call("神里");
//不自己写,直接调用父类的方法:
}
}
重写注意事项:
1、子类不能重写父类private 修饰的方法,即私有方法
2、子类访问父类的权限不能低于父类(public >默认(即函数前面不加修饰)>private)
java中继承的注意事项
1、java中只支持单继承,不支持多层继承。
2、java支持而多层继承。