继承的定义 和 覆写的定义

继承与覆写的性质

继承的引出

  • 继承性是java的三大特性之一,可为什么会有这一概念的诞生,它是为了解决哪些问题,这个是我们需要去了解的。
  • java中的简单java类是类和对象的基本形式,但如果我们所有东西都用简单java类的形式出现,则有可能会出现问题,下面我们来使用简单java类来描写一个图书类和一个数学图书类进行对比
Book类MathBook类
class Book{
private String title;
private String author;
private double price;<br
/> public Book(){
}
public Book(String title,String author,double price){
this.title=title;
this.author=author;
this.price=price;
}
public void setTitle(String title){
this.title=title;
}
public void setAuthor(String author){
this.author=author;
}
public void setPrice(double price){
this.price=price;
}
public String getTitle(){
return this.title;
}
public String getAuthor(){
return this.author;
}
public double getPrice(){
return this.price;
}
}
class MathBook {
private String title;
private String author;
private double price;
private String type;
public MathBook(){
}
public MathBook(String title,String author,double price,String type){
this.title=title;
this.author=author;
this.price=price;
this.type=type;
}
public void setTitle(String title){
this.title=title;
}
public void setAuthor(String author){
this.author=author;
}
public void setPrice(double price){
this.price=price;
}
public String getTitle(){
return this.title;
}
public String getAuthor(){
return this.author;
}
public double getPrice(){
return this.price;
}
public void setType(String type){
this.type=type;
}
public String getType(){
return this.type;
}
}
  • 在以上的程序中,我们实现了两个简单java类,这样的实现在整个程序中是没有语法错误的,但该程序中加粗的代码,两个类都存在。
  • MathBook类相较与Book类,只是多了一个成员属性 String type ,这样的情况,大大浪费了程序的性能,所以才会有继承性的特性存在

继承的定义

  • 了解了继承的特性,那么我们来研究与你继承的定义,在java中如果要进行继承的定义,我们可以用关键字 extends来实现,其基本语法如下

    class 子类 extendx 父类{}
    
  • 在很多面向对象的概念中,父类又被称为超类(super class),子类又被称为派生类,下面我们通过具体的程序来实现这种继承带来的优点

    class Book{
    	private String title;
    	private String author;
          private double price;
          public Book(){
          }
          public Book(String title,String author,double price){
          	 this.title=title;
          	 this.author=author;
          	 this.price=price; 
      }
    
          public void setTitle(String title){
          	  this.title=title;
          }
          public void setAuthor(String author){
          	  this.author=author;
          }
          public void setPrice(double price){
          	  this.price=price;
          }
          public String getTitle(){
          	  return this.title;
          }
          public String getAuthor(){
          	  return this.author;
          }
          public double getPrice(){
          	  return this.price;
          }
    }
    class MathBook extends Book{
    
    }
    public class YootkDemo{
    	public static void main(String arge[]){
    	MathBook book=new MathBook();
    	book.setTitle("线性代数");
    	book.setAuthor("马老师");
    	book.setPrice(49.8);
    	System.out.println(String.format("图书的名称为:%s 、图书的作者为:%s 、图书的价格为:%5.2f",book.getTitle(),book.getAuthor(),book.getPrice()));
    
    	}
    }
    //图书的名称为:线性代数 、图书的作者为:马老师 、图书的价格为:49.80
    
  • 在上面的程序中,我们可以看到,作为子类的MathBook中是没有的代码的,但依旧可以输出内容,这个情况就可以体现出,子类继承了父类的所有方法和属性。

  • 事实上子类的定义出来,是要比父类更加严格,同时所描述的范围更加小,那么此时我们可以考虑在子类中加入自己的操作结构,

  • 范例 在子类进行功能的扩充

    class Book{
    	private String title;
    	private String author;
          private double price;
          public Book(){
          }
          public Book(String title,String author,double price){
          	 this.title=title;
          	 this.author=author;
          	 this.price=price; 
      }
    
          public void setTitle(String title){
          	  this.title=title;
          }
          public void setAuthor(String author){
          	  this.author=author;
          }
          public void setPrice(double price){
          	  this.price=price;
          }
          public String getTitle(){
          	  return this.title;
          }
          public String getAuthor(){
          	  return this.author;
          }
          public double getPrice(){
          	  return this.price;
          }
    }
    class MathBook extends Book{
    	private String type;
    	public void setType(String type){
    		this.type=type;
    	}
    	public String getType(){
    		return this.type;
    	}
    
    }
    public class YootkDemo{
    	public static void main(String arge[]){
    	MathBook book=new MathBook();
    	book.setTitle("线性代数");
    	book.setAuthor("马老师");
    	book.setPrice(49.8);
    	book.setType("高等数学");
    	System.out.println(String.format("图书的名称为:%s 、图书的作者为:%s 、图书的价格为:%5.2f 、图书的学科为:%s",book.getTitle(),book.getAuthor(),book.getPrice(),book.getType()));
    
    	}
    }
    //图书的名称为:线性代数 、图书的作者为:马老师 、图书的价格为:49.80 、图书的学科为:高等数学
    
  • 这个时候MatehBook类既可以调用父类中的方法和属性,也可以调用自己类中定义的方法和属性

子类对象实例化流程

  • 现在我们已经掌握了继承的概念,也通过extends的关键字来实现继承的相关定义,但是我们要正确的使用继承开发,还必须了解子类对象的实例化过程
  • 在对象进行实例化的时候,所有使用关键字new实例化的对象,都必须调用类中的构造方法,下面我们来观察类继承构造方法的调用问题
class Book{
	public Book(){System.out.println("【Book中的构造方法】");
}
}
class MathBook extends Book{
	public MathBook(){System.out.println("【MathBook中的构造方法】");
}

}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();

	}
}
//【Book中的构造方法】
//【MathBook中的构造方法】
  • 通过结果我们可以知道,在继承的关系中,是先调用父类中的构造方法,再调用子类中的构造方法
  • 事实上这种情况是相当于在子类的构造中隐藏了一个**super()语句,这个super()**指的就是父类的无参构造
  • 范例 super() 构造
class Book{
	public Book(){
	System.out.println("【Book中的构造方法】");
}
}
class MathBook extends Book{
	public MathBook(){
	super();
	System.out.println("【MathBook中的构造方法】");
}
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();

	}
}
/*
【Book中的构造方法】
【MathBook中的构造方法】
*/
  • 此时,我们使用了super()的构造方法,结果同样没有改变,在使用super()方法的时候,必须要在构造方法的首行

继承的限制

  • 虽然通过继承可以实现父类方法的重用,但在java程序的设计过程之中,对于继承也有若干个限制
  • 限制一:一个子类只能继承一个父类,存在单继承的限制
  • 范例 观察错误的继承
class Book{   //图书类
}
class Emp{   //雇员类
}
class MathBook extends Book,Emp{
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();

	}
}
/*
程序的编译结果
YootkDemo.java:5: 错误: 需要'{'
class MathBook extends Book,Emp{
                           ^
1 个错误
*/
  • 在其他的编程语言中,这样的程序是不会出现错误的,这也体现了java单继承的概念

  • 限制二: 继承性虽然继承父类的所有的方法和属性,但是对于父类中的 privata 的属性及方法,不能直接的进行调用

  • 范例 观察访问的限制

    class Book{   //图书类
    	private String getInfo(){
    		return "【图书类中的方法】";
    	}
    }
    class MathBook extends Book{
    }
    public class YootkDemo{
    	public static void main(String arge[]){
    	MathBook book=new MathBook();
    	book.getInfo();
    
    	}
    }
    /*
    YootkDemo.java:11: 错误: 找不到符号
            book.getInfo();
                ^
      符号:   方法 getInfo()
      位置: 类型为MathBook的变量 book
    1 个错误
    */
    
  • private 的属性及方法具有封装性,当然是不能随意被调用的

覆写的定义

  • 在类继承当中结构中,我们可以实现一个类结构中的复用,但这里面也有一些问题,父类中的一些名称标记是具有代表性的,这个时候我们就希望可以被保留下来,并且根据自己的需要再进行扩写,这就是覆写

方法的覆写

  • 在类继承结构中如果定义了和父类相同的方法,那么这个时候就是方法的覆写,但是在进行覆写的时候,一定要保证,所有覆写的方法,返回值类型、参数类型及个数、方法名和父类的方法相同
  • 范例 实现方法的覆写
class Book{   //图书类
     public void print(){
     	 System.out.println("【Book类】我是一个图书类");
     }
	
}
class MathBook extends Book{
	  public void print(){
     	 System.out.println("【MathBook类】我是一个数学图书类");
     }
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();
	book.print();

	}
}
//【MathBook类】我是一个数学图书类
  • 此时MathBook类中的print()方法覆写了Book类中的方法,所以此时实例化的MathBook类调用的是覆写后的方法
  • 在程序设计中一旦有了覆写的概念之后,实际上就会出现一个问题,同一个方法父类出现,子类也可能出现,虽然父类的方法不能满足于子类全部的需要,但是也有很大的相同,此时就可以用super.父类方法() 来形式来进行调用
class Book{   //图书类
	public String getInfo(){
		return "【Book】这是一个图书类";
	}
}
class MathBook extends Book{  //数学图书类
	public String getInfo(){
		return super.getInfo()+"、【MathBook】这是一个数学图书类";
	}
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();
	System.out.println(book.getInfo());

	}
}
//【Book】这是一个图书类、【MathBook】这是一个数学图书类
  • 这样的方法就能使程序的代码得到更好的利用,也使代码的结构更加清晰。
  • 如果在子类中调用覆写过的父类的方法,那么就不要使用this.方法()去调用父类中覆写的方法,若处理不当,会出现程序溢出的情况,并且程序的可读性也会有很大的限制,所以,如果我们要在子类中调用父类的方法,我们就用super.方法(),在子类中调用自己的方法就用this.方法(),这样就会避免错误的调用。

方法覆写的限制

  • 方法的覆写是有一个访问权限的限制的,子类覆写的方法不能比父类的访问权限更加严格,我们现在接触到的的访问控制权限实际上有3个,其大小关系为:private<default<public ,按照这样的的概念限制,使用default修饰的方法,我们可以用default和public的来覆写,使用public修饰的方法,我们可以用public来覆写
  • 范例 观察正确的覆写
class Book{   //图书类
	 String getInfo(){
		return "【Book】这是一个图书类";
	}
}
class MathBook extends Book{  //数学图书类
	public String getInfo(){
		return "【MathBook】这是一个数学图书类";
	}
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();
	System.out.println(book.getInfo());

	}
}
//【MathBook】这是一个数学图书类
  • 如上面的程序,父类使用了default(默认的),子类使用了public的权限来覆写。
  • 事实上由于private的封装性,private的方法是无法被覆写的
  • 范例 private的方法无法覆写
class Book{   //图书类
	 private String getInfo(){
		return "【Book】这是一个图书类";
	}
	public void fun(){
		System.out.println(this.getInfo());   //父类定义的方法,子类可以直接继承
	}
}
class MathBook extends Book{  //数学图书类
	public String getInfo(){
		return "【MathBook】这是一个数学图书类";
	}
}
public class YootkDemo{
	public static void main(String arge[]){
	MathBook book=new MathBook();
	book.fun();

	}
}
//【Book】这是一个图书类
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值