java的继承 inheritance

1,为什么需要继承

        假设我们要写几个动物的类:
     小猫:眼睛,耳朵,尾巴,鼻子,爪子。。。。
     小狗:眼睛,耳朵,尾巴,鼻子,爪子。。。。
     小羊:眼睛,。。。。。。
     很显然,这些类中是有许多共同之处的,比如它们都有眼睛,耳朵,尾巴等,不同的只是各个成员(眼睛,尾巴等)的具体内容,如眼睛的大小,尾巴的颜色,长短等而已。如果每个类都单独来写,某些相同的代码就需要重复写许多遍,但怎样能解决这个问题呢?可不可以将具有相同功能的内容只写一次呢?这时,就需要用到继承(inheritance)。
     

2,继承的作用

     1,提高的代码的重用性;
     2,提高代码的可扩展性

3,继承的格式

    java中继承的关键字:extends
    格式:
          public class 类名(子类,派生类) extends 类名(父类,基类){
                          
          }
     注意:1,java中的继承是单继承,也就是说一个子类只能继承一个父类,但一个父类可以被多个子类所继承;
                2,子类可以继承到父类中的所有属性和方法,与访问修饰符无关。访问修饰符只能限制对象访问方法的范围。 
                3,子类可以定义父类中没有的属性和方法,但也只能由子类的对象进行调用。
                4,子类继承父类之后,实例化子类对象时,系统会首先实例化父类对象。
 举个例子:
package Extends;

public class Student{       
	//父类 学生类
	public String name;
	
	public void study(){     //学习方法
		System.out.println("学生的名字是:"+name);
	}
	
	public void setName(String name){    //设置名字方法(参数)
		this.name = name;
	}
	
	public void eat(){
		System.out.println("学生每天都在食堂吃饭");
	}
	
	public void rest(){
		System.out.println("学生每天都在宿舍休息 ");
	}
	
	
}
package Extends;

public class UNStudent extends Student{
	//子类  大学生类

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		UNStudent uns = new UNStudent();
		uns.setName("张三");
		uns.study();
		uns.cet6();
		
	}
	
	public void cet6(){     //子类特有的方法
		System.out.println("大学生不想考六级!!!");
	}
	
}

4,自动转型

        1),自动转型的条件是什么?
                        必须存在继承关系。

     2),自动转型的格式:
                        一,将子类对象的类型定义成父类对象的类型,也就是说,子类对象的类型可以自动转型成父类对象类型。
                             父类名  对象名  = new 子类构造方法(参数值,...);
              
Student un = new UNStudent();
                         注意:1,子类类型转成父类类型后不能调用子类特有的方法;
                                    2,方法重写时,先调用子类还是父类的方法,取决于new关键字之后的类。
                                         
                        二,访问修饰符  返回值类型 方法名(父类名  参数名,...){

               }
               子类名  对象名  = new 子类构造方法(参数值,...);
               方法名(对象名)

      3),自动转型会引发什么问题?
                无法调用子类特有的属性和方法。
                原因:java编译和运行机制的不同
                           java编译时,编译的是文件,是根据对象名的类型进行编译的。如果对象名调用的属性和方法在对象名的类型中存在,就会通过编译,否则不通过;
                          而运行时,会使用对象名中存储的对象的堆内存首地址。调用方法时,会根据对象名中存入的首地址优先进行调用,如果对象名中没有才会去调用父类的。
 

5,强制转型

   1),强制转型的条件是什么?
                        1,必须存在继承关系
                        2,之前实例化的对象是子类的对象(也就是说,如果一个对象可以被强制转型,那么它肯定在前面某个地方被自动转型过)

   2),强制转型的格式:
                        子类名  子类对象名 =(子类名)父类对象名;

例子:
		Student stu = new UNStudent();     //将子类对象定义为父类类型(自动转型)
		stu.setName("李四");
		stu.study();
		//对象stu不能调用子类特有的方法cet6
		
		UNStudent stu2 = (UNStudent)stu;     //将父类类型的对象stu强制转换成子类类型(强制转型)
		stu2.cet6();

6,方法重写 override

     1),什么时候需要方法重写:
              当父类中存在一个方法,子类中也有这个方法,但子类中方法的具体实现与父类中不同时,重写该方法。

     2),方法重写的条件:
              1,必须存在继承关系;
              2,子类方法的访问修饰符必须大于或等于父类方法的访问修饰符;
              3,子类方法的返回值类型,方法名以及参数都必须与父类一致;
              4,方法的实现不能相同。
package Extends;

public class JUStudent extends Student{
	//子类 中学生类
	public void study(){    //方法的重写
		System.out.println(name + "是中学生");
	}
	
	public static void main(String[] args){
		JUStudent jus = new JUStudent();
		jus.setName("王五");
		jus.study();
		
		Student stu3 = new JUStudent();
		stu3.setName("赵六");
		stu3.study();
	}

}
注意:在子类重写父类的某方法后,最后调用时调用的是子类的方法。这种情况下,如果一定要调用父类中的成员函数,可以使用super关键字。调用方法是:super.函数名

举个例子:
父类:
package Jicheng;

public class Dialog_01 {
	protected String title;
	
	public Dialog_01(String title){
		this.title = title;
	}
	
	public void show(){
		System.out.println(title+"对话框显示");
	}
    

}
子类:
//子类
package Jicheng;

public class FrontDialog extends Dialog{
	
	private String frontName;
	public FrontDialog(String title,String frontName){  
		this.title = title;
		this.frontName = frontName;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FrontDialog fd = new FrontDialog("字体","宋体");

	}

}
此时,子类public FrontDialog(String title,String frontName)处会报错。因为只要实例化子类对象,系统就会自动先实例化一个父类对象与之对应,当然此时调用的是父类没有参数的构造函数。
解决方法:
1),给父类增加一个无参的构造函数
//解决方法1:给父类增加一个没有参数的构造方法
package Jicheng;

public class Dialog_01 {
	protected String title;
	
	public Dialog_01(){}
	
	public Dialog_01(String title){
		this.title = title;
	}
	
	public void show(){
		System.out.println(title+"对话框显示");
	}
    

}
2)在子类的构造函数中,第一句用super给父类的构造函数传参数
//解决方法2:在子类的构造方法中,第一句用super()给父类构造函数传参数
package Jicheng;

public class FrontDialog_02 extends Dialog{
	private String frontName;
	public FrontDialog_02(String title,String frontName){ 
		super(title); 
		this.frontName = frontName;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FrontDialog_02 fd = new FrontDialog_02("字体","宋体");

	}
}
注意:用super给父类传参时,必须写在子类构造函数的第一句,且传入的参数必须和父类构造函数中参数列表类型相匹配。

7,接口

     1),为什么需要接口?
           一般情况下,父类都比子类更加抽象,因为父类中的属性和方法比子类更少,而且父类的方法中,我们只能笼统的描述,而不能像子类方法一样更为具体。
           所以当我们只知道父类的对象应该做什么,但不知道该怎样做时,我们就可以定义这样的一个类,类中的方法只有方法的定义,没有方法体,这个类我们就叫它接口。

     2),定义接口的格式;
            public interface 接口名  extends 接口,... {

//定义常量
public static final 数据类型  常量名  = 值;

//定义抽象方法
public abstract 返回值类型  方法名(数据类型 参数名,...);

}
注意:
1.接口只有一个访问修饰符public。
2.接口默认会提供public、static、final、abstract关键字。
3.接口不能实例化对象。
package Extends;
//定义一个接口(一种数据类型),主要用来扩展子类
//**只有方法体,但没有对方法的定义**

public interface Person {    //接口的属性默认为public static final(公共的静态常量)
	public static final int num = 1000;
	
	void eat();    //接口中的方法默认为public abstract(公共的抽象方法)
	public abstract void rest();

}
    
    3),实现接口:
           实现(继承)接口的关键字:implements
格式:
public class 类名  extends  类名   implements 接口,... {
//注意:类必须要实现(重写)接口中所有的抽象方法。(包含接口继承父接口中的抽象方法)

}

            一个类可以继承多个接口。
package Extends;

public class Student implements Person{       
	
	public static void main(String[] args){     //实现person接口
		Person per = new Student();     
		per.eat();
		per.rest();
	}

}

8,抽象类

     1),什么是抽象类:
           父类中如果规定一个抽象函数:abstract 函数名() ,其必须被重写。含有抽象函数的类就是抽象类,也必须用abstract修饰。
   
     注意:1,抽象类不能被实例化;
                2,抽象函数必须被重写,除非子类也是抽象类;
                3,抽象类中也可以含有普通成员函数。

9,final关键字

     1,用final修饰一个类:
                   表示该类不能被继承
    2,用final修饰一个函数:
                   表示该类在被子类继承的情况下,该函数不能被重写
    3,用final修饰一个成员变量:
                   表示该成员变量的值不许改变,也就是说,不允许重新赋值。因此,一般用final关键字定义一个常量。

                  



     








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaInheritance继承)是面向对象编程(OOP)中的一个重要概念。它使得一个可以从另一个(称为父)继承属性和方法,从而避免了重复编写代码的麻烦。在Java中,使用关键字extends来实现继承。 以下是JavaInheritance的一些重要概念: 1. 父和子:父继承,子继承。 2. 继承型:Java中支持单继承,即每个子只能继承一个父。但是,Java中也支持多重继承,即一个可以同时继承多个接口。 3. 访问修饰符:在Java中,继承也受到访问修饰符的限制。如果一个被声明为public,则其所有公共方法和属性都可以在继承中使用。如果一个被声明为private,则其所有私有方法和属性都不能在继承中使用。 4. 方法覆盖:当子继承时,子可以重写父中的方法。这称为方法覆盖。方法覆盖提供了一种重写或改善父中方法的机制。 5. super关键字:子可以使用super关键字来访问其父中的方法和属性。这对于在子中覆盖父方法时必要的。 6. 构造函数:子可以调用其父的构造函数来初始化其继承的属性。这可以通过使用super关键字和父构造函数的参数列表来实现。 继承Java中的一个基本概念,它使得代码更加简洁、可读性更高,并且提供了一种扩展和改进现有代码的方式。然而,在使用继承时,需要注意继承层次的设计和合理的访问修饰符的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值