java学习核心(2) java 三大特性继承

1、什么是java中的继承

继承在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的方法和属性。主要是用于代码的复用。

2、java 继承的理解

public class Husband {
	
	private  String  name;
	
	private  int  age;
	
	private  String sex;
	
	private  Wife wife;
}

public class Wife {
	
	private  String  name;
	
	private  int  age;
	
	private  String sex;
	
	private  Husband husband;

}

这里可以看出 Husband 和 Wife 类中除了 Wife  和 Husband  两个成员属性不一样,其余都相同。作为一个像最大限度使用代码复用,我们是不能够忍受这样重复的代码的。
那我们如何解决代码重复问题了?我们可以使用继承来实现。

从常识中我们知道丈夫、妻子,而且都有一些共性,有名字、年龄、性别、头等等,而且他们都能够吃东西、走路、说话等等共同的行为,所以从这里我们可以发现他们都拥有人的属性和行为,同时也是从人那里继承来的这些属性和行为的。

从上面我们就可以基本了解了继承的概念了, 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码,能够大大的提高开发的效率。

public class Person {
	private  String  name;
	private  int  age;
	private  String sex;
}
public class Husband  extends  Person{
	
	private  Wife wife;
}
public class Wife extends Person {
	private Husband husband;

}

      对于Wife、Husband使用继承后,除了代码量的减少我们还能够非常明显的看到他们的关系。
       继承所描述的是“is-a”的关系,如果有两个对象A和B,若可以描述为“A是B”,则可以表示A继承B,其中B是被继承者称之为父类或者超类,A是继承者称之为子类或者派生类。
       实际上继承者是被继承者的特殊化,它除了拥有被继承者的特性外,还拥有自己独有得特性。例如猫有抓老鼠、爬树等其他动物没有的特性。同时在继承关系中,继承者完全可以替换被继承者,反之则不可以,例如我们可以说猫是动物,但不能说动物是猫就是这个道理,其实对于这个我们将其称之为“ 向上转型”,

3、使用继承需要记住三句话


1、子类拥有父类非private 属性和方法。

 2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

3、 子类可以用自己的方式实现父类的方法。(重写)

       综上所述,使用继承确实有许多的优点,除了将 所有子类的共同属性放入父类实现代码共享避免重复外
可以使得修改扩展继承而来的实现比较简单。

       诚然,讲到继承一定少不了这三个东西:构造器、protected关键字、向上转型。

 4、构造器

        通过前面我们知道子类可以继承父类的属性和方法,除了那些private的外还有一样是子类继承不了的---构造器。
对于构造器而言,它只能够被调用,而不能被继承。 调用父类的构造方法我们使用super()即可。
       对于子类而已,其构造器的正确初始化是非常重要的,而且当且仅当只有一个方法可以保证这点:在构造器中调用
父类构造器来完成初始化,而父类构造器具有执行父类初始化所需要的所有知识和能力。
public class Person {
	private  String  name;
	private  int  age;
	private  String sex;
	public Person() {
		System.out.println("父类的构造器");
	}
}
public class Husband extends Person {

	private Wife wife;

	public Husband() {
		System.out.println("这个是子类的构造器");
	}

	public static void main(String[] args) {
		Husband h = new Husband();
	}

}
         通过这个示例可以看出,构建过程是从父类“向外”扩散的,也就是从父类开始向子类一级一级地完成构建。而且我们并没有显示的引用父类的构造器,这就是java的聪明之处: 编译器会默认给子类调用父类的构造器。

       但是,这个默认调用父类的构造器是有前提的:父类有默认构造器。如果父类没有默认构造器,我们就要必须显示的使用super()来调用父类构造器,否则编译器会报错:无法找到符合父类形式的构造器。

public class Person {  
    protected String name;  
    protected int age;  
    protected String sex;  
      
    Person(String name){  
        System.out.println("Person Constrctor-----" + name);  
    }  
}  
  
public class Husband extends Person{  
    private Wife wife;  
  
    Husband(){  
        super("chenssy");  
        System.out.println("Husband Constructor...");  
    }  
      
    public static void main(String[] args) {  
        Husband husband  = new Husband();  
    }  
}  
  
Output:  
Person Constrctor-----chenssy  
Husband Constructor...  

总结:对于继承而言,子类会调用父类的默认的构造方法,如果父类没有默认的构造方法,子类必须要显示指定父类的构造器。而且必须是子类构造器中做的第一件事情。(也就是第一行代码)。

5、protected关键字

       private访问修饰符,对于封装而言,是最好的选择,但这个只是基于理想的世界,有时候我们需要这样的需求:我们需要将某些事物尽可能地对这个世界隐藏,但是仍然允许子类的成员来访问它们。这个时候就需要使用到protected。
      对于protected而言,它指明就类用户而言,他是private,但是对于任何继承与此类的子类而言或者其他任何位于同一个包的类而言,他却是可以访问的。

public class Person {
	private  String  name;
	private  int  age;
	private  String sex;
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "name  is"+name;
	}
}
public class Husband extends Person {


	private Wife wife;


	@Override
	public String toString() {
		// TODO Auto-generated method stub
		setName("你凹");
		return super.toString();
	}


	public static void main(String[] args) {


		Husband husband = new Husband();


		System.out.println(husband.toString());


	}
}

从上面示例可以看书子类Husband可以明显地调用父类Person的setName()。
       诚然尽管可以使用protected访问修饰符来限制父类属性和方法的访问权限,但是最好的方式还是将 属性保持为private(我们应当一致保留更改底层实现),通过protected方法来控制类的继承者的访问权限。

6、向上转型

public class Person {
	public void display() {
		System.out.println("Play Person...");
	}

	static void display(Person person) {
		person.display();
	}
}

public class Husband extends Person {
	public static void main(String[] args) {
		Husband h = new Husband();
		display(h);
	}
}

       在继承中我们就说到继承是is-a的关系, 猫继承动物,所以说猫是动物。或者说猫是动物中的一种,这个猫就看做动物的向上转型。
在这我们通过Person.display(husband)。这句话可以看出husband是person类型。
       将子类转换成父类,在继承关系上面是向上移动的,所以一般称之为向上转型。由于向上转型是从一个叫专用类型向较通用类型转换,所以它总是安全的,唯一发生变化的可能就是属性和方法的丢失。这就是为什么编译器在“未曾明确表示转型”活“未曾指定特殊标记”的情况下,仍然允许向上转型的原因。


7、总结


上面讲了继承所带来的诸多好处,那我们是不是就可以大肆地使用继承呢?送你一句话:慎用继承。

       首先我们需要明确,继承存在如下缺陷:

         1、父类变,子类就必须变。

         2、继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的。

         3、继承是一种强耦合关系。

       所以说当我们使用继承的时候,我们需要确信使用继承确实是有效可行的办法。那么到底要不要使用继承呢?《Think in java》中提供了解决办法:问一问自己是否需要从子类向父类进行向上转型。如果必须向上转型,则继承是必要的,但是如果不需要,则应当好好考虑自己是否需要继承。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值