黑马程序员_面向对象的三大特性之——继承

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

一、继承的概述

1、什么是继承?

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。那个单独的类称为父类或者超类、基类,多个类称为子类。子类可以继承父类中除private修饰的属性和行为。比如现实生活中的猫、老虎都属于猫科动物,可以抽取出一个猫科动物类来描述猫和老虎的共性信息。 父类还可以一级级的向上抽取,比如猫科动物类属于哺乳动物类,哺乳动物属于动物等。
在java中通过extends关键字让类与类之间产生继承关系。比如:class Cat extends Felid{}
2、继承的好处
1)继承的出现提高了代码的复用性。
父类中定义了子类共性的内容,那么子类继承父类就相当于在子类中也拥有了这些内容,不用每个子类都再定义一遍了。
2)继承的出现让类与类之间产生了关系,提供了多态的前提。
继承是多态的基础,关于多态,在后面的博客中说明。
3、继承的弊端
破坏了类的封装。因为父类中的数据可以被子类使用,而不再是只归父类自己使用,降低了程序的安全性。
二、继承的特点
1、在java只支持单继承,不支持多继承。
一个类只能有一个父类,不可以有多个父类。
class SubDemo extends Demo{}    //OK,没有问题
class SubDemo extends Demo1,Demo2...//ERROR,不可以这样继承
因为多继承容易带来安全隐患:当多个父类中定义了相同的功能,而且功能的内容不同,那么子类对象不确定要运行哪一个。
但是java保留这种机制,并用另一种体现形式来完成表示,那就是多实现。实现多个接口以扩展功能。
2、Java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
注意: 不要仅为了获取其他类中某个功能而去继承, 类与类之间要有所属" is a " 关系,子类是父类的一种。
比如猫继承猫科动物,那么猫是猫科动物中的一种,这样符合现实生活中的逻辑。
那么猫可以陪人玩耍,狗也可以陪人玩耍,让狗继承猫类,狗不就有这个功能了吗?但是,现实生活中,狗不是猫的一种,不符合逻辑。

三、super关键字

super关键字的用法和this关键字的用法几乎一致。

this关键字代表的是本类对象的引用;super关键字代表的是父类对象的引用。

当子父类出现同名成员时,可以用super进行区分。
例如子类和父类中都有一个变量name,那么想要访问父类的name变量,可以super.name;访问本类的name变量,可以this.name。
子类要调用父类构造函数时,可以使用super();语句。
在对子类对象进行初始化时,父类的构造函数也会运行。那是因为子类的构造函数默认第一行有一句隐式的语句:super();,这条语句会访问父类中空参数的构造函数。而且,子类中所有的构造函数默认第一行都是super();。
为什么会有一条隐式的语句呢?这是因为父类中的数据子类可以直接获取。在创建子类对象时,需要先到父类中查看一下是如何对这些数据进行初始化的。
如果想要访问父类中指定的构造函数,可以通过手动定义super语句来指定。

四、函数的覆盖

1.什么是函数的覆盖?

当子类中出现和父类中一模一样的函数时,子类对象调用该函数,会运行子类函数中的内容。这种情况成为函数的覆盖或者重写

父类中私有的方法子类无法覆盖。因为子类访问不到父类私有的数据。

在子类覆盖方法中,想要继续使用被覆盖的方法时,可以通过super.方法名调用。

当子类继承父类,便沿袭了父类的功能到子类中。子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新的功能,而是使用覆盖特性,保留父类的功能定义,并重写子类特有的功能内容。比如下面代码中Student类继承People类,People类有一个回家的方法:goHome(),Student类也有回家的方法,但是Student类想特别说明自己是坐公交车回家,就可以重写People类的goHome()方法,这就是函数的覆盖的体现。

People类:父类

package cn.itcast.ch03;
/**
 * 人类,学生类的父类
 * @author 中关村阿旺
 *
 */
public class People {
	private String name;    //姓名
    private int age;       //年龄
    private String sex;    //性别
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
    public People(){
    	
    }
    public People(String name,int age,String sex){
    	this.setName(name);
    	this.setAge(age);
    	this.setSex(sex);
    }
    //回家的方法
    public void goHome(){
        System.out.println("回家。");
    }
}

Student类:子类

package cn.itcast.03;
/**
 * 学生类
 * @author 中关村阿旺
 *
 */
public class Student extends People{
    
    private String className;   //班级名称
    //获得班级名称
    public String getClassName() {
		return className;
    }
    //设置班级名称
    public void setClassName(String className) {
	        this.className = className;
    }
    //在教室上课的方法(学生类特有的方法)
    public void inClassRoom(){
	        System.out.println("学生的姓名:"+this.getName()+",年龄:"+this.getAge()+",性别:"+this.getSex()+",所在班级:"+getClassName()+",正在听课!");
    }
	public Student(){
		super();
	}
	public Student(String name,int age,String sex,String className){
		super(name,age,sex);
		this.setClassName(className);
	}

    //重写了父类中回家的方法
	@Override
	public void goHome() {
		System.out.println("坐公交。");
	}
}

 2、覆盖时的注意事项:

1)子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

2)静态方法只能覆盖静态方法。

3、方法的覆盖(重写)与方法的重载的区别:

方法的重写必须保证子父类的方法名称一模一样。

方法的重载只看同一类中同名函数的参数列表。

五、子类的实例化过程

1、子类中所有的构造函数默认都会访问父类中空参数的构造函数。
因为每一个构造函数的第一行都有一条默认的语句super(); 子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
2、当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。

六、final关键字

1、final可以修饰类,方法,变量。
2、final修饰的类不可以被继承。因为final修饰的类是最终的类,被子类继承了,子类就可以复写它的方法,这样显然不合适。
3、final修饰的方法不可以被覆盖。
4、final修饰的变量是一个常量。只能被赋值一次。既可以修饰局部变量,也可以修饰成员变量。
5、内部类只能访问被final修饰的局部变量。
七、抽象类
1、什么是抽象类?什么是抽象方法?
当多个类中出现相同功能(方法),但是功能的具体实现方式不同。这时可以进行向上抽取,只抽取功能定义,而不抽取功能主体,那么抽取出来的方法就是抽象方法。存在抽象方法的类就是抽象类
抽象类和抽象方法都用关键字abstract修饰。
2、抽象类和一般类的区别:
抽象类和一般类没有太大的区别,只不过,该事物出现了一些看不懂的、不确定的部分,但也是该事物的功能,需要明确出来。但是无法定义功能的具体实现方式,那么就通过抽象方法来表示。抽象类比一般类多了一个抽象方法。
3.抽象类的特点:
1)抽象类和抽象方法必须用abstract关键字来修饰。
抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符abstract返回值类型  函数名(参数列表);
2)抽象类不可以被实例化,也就是不可以用new创建对象。
因为抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。 而且抽象类即使创建了对象,调用抽象方法也没有意义。
3)抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

八、接口

1、定义格式:
interface 接口名称{}
接口中的成员修饰符是固定的。
成员常量:public static final(公共静态常量)
成员函数:public abstract
发现接口中的成员都是public的。
2、接口的作用:
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
子类可以实现多个接口,以便重写接口中的功能。

3、接口的特点:

1)接口是对外暴露的规则
2)接口是程序的功能扩展
3)接口的出现降低耦合性
4)接口可以用来多实现
5)类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
6)接口与接口之间可以有继承关系。而且一个接口可以继承多个接口

4、接口与抽象类的共性与区别:

共性:都是不断抽取出来的抽象的概念。

区别:

1)抽象类体现继承关系,一个类只能单继承;接口体现实现关系,一个类可以多实现。
2)抽象类是继承,是 "is a "关系;接口是实现,是 "like a"关系。
3)抽象类中可以定义非抽象方法,供子类直接使用;接口的方法都是抽象方法,接口中的成员都有固定修饰符,都是全局静态常量。
 

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值