第十三讲 继承

第十三讲 继承

1 面向对象三大特征

面向对象三大特征:
	封装
	继承
	多态
关于封装:
	类就是一种封装。以前学习C,数据和方法都是暴露在外面的。C也有封装,比如结构体。其实结构体就是类的原型。
	类是一种封装,它将这一类事物的共有的属性和方法封装在一起。
	比如:我们的手机,你需要知道实现的原理吗?你只要知道怎么用就行。这就是一种封装。它屏蔽了复杂的实现过程,给用户提供了简单的操作入口。比如手机不要外壳,不封装,那么里面的重要的元器件都暴露在用户面前,这样很危险。
	封装确保了数据的安全,使得数据更加私密。使用者不需要直接操作数据,只要使用开发者提供的界面(接口)就可以了。
	比如:芯片,国产芯片始终没有达到世界领先的水平,那么就需要向国外购买,国外的公司卖给我们的是一个完整的产品,不会给我们制作的方式方法,技术层面是被封装了,被屏蔽了,确保他们技术的安全性。

我们在写javabean的时候,见过封装。比如get、set方法(getter and setter)。比如overload,只给用户提供一个方法,和传入方法参数的规范,用户就可以操作。
封装的案例如下:
public class Chinese 
{
	private int id;
	private String name;
	private static String country = "China";

	public Chinese() {}
	public Chinese(Chinese this, int id, String name) {
		
		this.id = id;
		this.name = name;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	public int getId() {
		return this.id;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
	public String toString() {
		return "[ " + id + ", " + name + " ]"; 
	}
}
// 用户层面只要如下代码所示,使用即可。根本不知道封装的内部实现。
public class Test {
    public static void main(String[] args) {
        Chinese c = new Chinese();
        c.getId();
        c.setId();
        System.out.println("fawefwe");//我们不知道他怎么实现的,只知道这么用就行
    }
}

2 继承

继承:extends
什么是继承?为什么要继承?
继承:
	在java中的继承跟我们在现实中的继承一样。我继承我父亲的财产,我继承我父亲的性格,我继承我祖辈的基因。
	我们可以看到,我继承我父亲的基因,是不是表示我的基因是我父亲的。我继承我父亲的财产,是不是就是说我的这部分财产是我父亲的。
	继承又可以表示为:is-a的关系。是一个。
	比如:
	Animal
	Cat: Cat is an Animal
	Dog: Dog is an Animal
	
	Person:
	ZhangSan is a Person
为什么要继承?
	
public class Animal 
{
	private String name;
	private String type;
	
	public void eat() {
		
	}
	
	public void sleep() {
		
	}
}


public class Dog 
{
	private String name;
	private String type;
	
	public void eat() {
		
	}
	public void sleep() {
		
	}
}


public class Cat 
{
	private String name;
	private String type;
	
	public void eat() {
		
	}
	public void sleep() {
		
	}
}

上面的代码基本一致,基本重复,这样写下去太过于冗余。
java给我们提供了一个继承的机制。可以解决这种冗余。
语法:
	父类:
	public class Animal{}
	子类:
	public class Dog {}
	我们希望子类和父类建立起继承的关系:使用关键字 extends
	public class Dog extends Animal {} 
	
public class Animal 
{
	private String name;
	private String type;
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
	public void eat() {
		System.out.println("eating");
	}
	
	public void sleep() {
		System.out.println("sleeping");
	}
}
// --------------------------------------父类

public class Dog extends Animal
{
}
// -------------------------------------子类
public class Cat extends Animal
{
}
// -------------------------------------子类


// ---------------------- Test Code -----------------
public class ExtendsTest 
{
	public static void main(String[] args) 
	{
		Dog dog = new Dog();
		dog.eat();
		dog.setName("哈巴狗");
		System.out.println(dog.getName());

		Cat cat = new Cat();
		cat.setName("醉猫");
		System.out.println(cat.getName());
	}
}
/* 输出结果:
        eating
        哈巴狗
        醉猫
*/
从上面代码中可以看出,使用继承以后,解决了代码的冗余。
从上面的代码中分析:
	首先子类继承了父类。
	继承了哪些内容:
		继承了成员属性
		继承了成员方法(不包括被private修饰的)
		也继承了静态方法(不包括被private修饰的)
		父类中private修饰的方法是父类独有的,不会被继承。
	
	继承中的一个关系问题:
		父类的引用指向子类的对象:这是可以的,这可以说Dog是Animal
		子类的引用指向父类的对象:这是不可以的,这可以说Animal是Dog,显然不对。
	
构造方法被继承了吗?
	假如构造方法被继承了。
	那么如果在父类中有一个无参数的构造方法,在子类中没有无参数的构造方法,是可以构造子类对象的。
	如果父类的构造方法被子类继承了,那么就可以实现子类的引用指向父类的对象。
	因为子类拥有父类的构造方法,Dog dog = new Animal();
	从实验中我们可以看到构造方法并没有被继承。

在这里插入图片描述

public class Animal 
{
	private void run() {
		System.out.println("running");
	}
}

public class Cat extends Animal {
    
}
// 父类中有private修饰的方法,子类在访问的时候会编译报错
public class ExtendsTest 
{
	public static void main(String[] args) 
	{
		Cat cat = new Cat();
		cat.run();
	}
}
/*
  ExtendsTest.java:13: 错误: 找不到符号
                cat.run();
                   ^
  符号:   方法 run()
  位置: 类型为Cat的变量 cat
1 个错误
*/

// 也就是父类私有的方法,子类无法继承。但是父类私有的成员属性,子类是继承了的。只不过还了中方式去访问。通过公开的方法区访问。
// 构造方法是否被继承的实验代码
public class Animal 
{
	private String name;
	private String type;

	public Animal() {}

	public Animal(String name, String type) {
		this.name = name;
		this.type = type;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
	public void eat() {
		System.out.println("eating");
	}
	
	public static void sleep() {
		System.out.println("sleeping");
	}

	public void run() {
		System.out.println("running");
	}
}

public class ExtendsTest 
{
	public static void main(String[] args) 
	{
		Dog dog = new Dog();
		dog.eat();
	}
}
/*
ExtendsTest.java:5: 错误: 无法将类 Dog中的构造器 Dog应用到给定类型;
                Dog dog = new Dog();
                          ^
  需要: int
  找到:    没有参数
  原因: 实际参数列表和形式参数列表长度不同	
*/
// 这也证明了构造方法没有被继承。

3 进一步了解继承

子类继承父类,拥有父类的属性和方法(非private修饰的)。
private的属性子类无法直接访问,但可以通过方法父类提供的方法间接的访问。

父类的能力是有限的,子类拥有了父类的一些方法和属性之后,还可能满足不了需求。
比如: Animal这个父类中,有eat() sleep() run()
但是Dog这个子类,它有它自己的特有的行为。
比如:狗会摇尾巴。Dog类要有一个waveTail()方法。
我们应该怎么做呢?
	在子类中定义。
	为什么可以这样呢?
		因为青出于蓝而胜于蓝。
		也就是说,在子类中可以定义很多子类特有的行为和属性。这些方法和属性是父类没有的,可以在子类中进行定义。
		(记住)一个父类可以有很多子类,但是一个子类只能有一个父类。java中不能多继承,只能继承一个父类。
		如果一个类没有通过extends继承任何类,实际上它也继承了一个老祖宗类,这个类的名字叫做Object;
		继承是可以传递的,可以从A继承B继承C继承D,这样是可以的。
		A extends B {}
		B extends C {}
		C extends D {}
		D的级别是最高得
		C拥有D的属性、方法(非private),
		B拥有C和D的属性和方法(非private)
		A拥有BCD的属性、方法(非private)。
		我们看得出来:子类的能力要比父类强大。父类一旦被定义,子类一旦继承,父类除了private的方法之外,其他的基本上被子类所有。
		继承这种机制,父类其实是一个抽象,是子类共性的集合。或者是说父类是子类共有属性和方法的一个集合。是子类共有属性、方法的模板。
		有了继承之后,好处很多,比如减少代码的冗余。但这不是最主要的功能。
		最最重要的功能是为多态提供了实现的可能。
public class Dog extends Animal
{
	public void waveTail() {
		System.out.println("摇尾巴!!");
	}
	
}

public class ExtendsTest 
{
	public static void main(String[] args) 
	{
		Dog dog = new Dog();
		dog.eat();
		dog.setName("哈巴狗");
		dog.waveTail();
		System.out.println(dog.getName());
		dog.sleep();// 可以吗?因为我们说过,Dog is an Animal
		// 也就是说,dog是一个animal,它是动物类的一个子类。
		Dog.sleep();// 可以吗?可以,本质上是谁在调用?
		dog.sleep();// 本质上是谁在调用?

		Cat cat = new Cat();
		cat.setName("醉猫");
		System.out.println(cat.getName());
		cat.run();
		Animal a = new Dog();// 这样可以吗?父类的引用 指向 子类的对象
		// 狗狗是一个动物 这种说法成不成立?成立
		//Dog td = new Animal("泰迪", "宠物狗");//这样可以吗?
		// 动物是狗 成立吗?
		// 错误: 不兼容的类型: Animal无法转换为Dog
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值