Java学习个人备忘录之继承

继承的好处
1. 提高了代码的复用性。
2. 让类与类之间产生了关系,给第三个特征多态提供了前提。

java中支持单继承,不直接支持多继承,但对C++中的多继承机制进行改良。
java支持多层继承。

C继承B,B继承A,就会出现继承体系。

当要使用一个继承体系时:
1. 查看该体系中的顶层类,了解该体系的基本功能。
2. 创建体系中的最子类对象,完成共能的使用。

什么时候定义继承呢?
当类与类之间存在着所属关系的时候,就定义继承,xxx是yyy中的一种,  xxx extends yyy。

class Person
{
	String name;
	int age;
}

class Student extends Person   //继承
{
	// String name;
	// int age;
	void study()
	{
		System.out.println(name+"...student study...."+age);
	}
}

class Worker extends Person
{
	// String name;
	// int age;
	void work()
	{
		System.out.println("worker work");
	}
}

class ExtendsDemo
{
	public static void main(String[] args)
	{
		Student s = new Student();
		s.name = "zhangsan";
		s.age = 20;
		s.study();
	}
}

在子父类中,成员的特点体现
1.成员变量
2.成员函数
3.构造函数

1. 成员变量
当本类的成员和局部变量同名时,用this区分;
当子父类中的成员变量同名时,用super区分父类。

this和super的用法很相似。

this:代表一个本类对象的引用。
super:代表一个父类的空间,并不代表父类对象。

class Fu
{
	int num = 4;
}

class Zi extends Fu
{
	int num = 5;
	void show()
	{
		System.out.println(super.num+"..."+num);
	}
}

class ExtendsDemo2
{
	public static void main(String[] args)
	{
		Zi z = new Zi();
		z.show();
	}
}

2. 成员函数
当子父类中出现成员函数一模一样的情况,会运行子类的函数。
这种现象,称为覆盖操作,这时函数在子父类中的特性。
函数两个特性:
1.重载. 同一个类中,overload
2.覆盖. 子类中,覆盖也称为重写,override

覆盖注意事项:
1.子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。
2.静态只能覆盖静态,或被静态覆盖。

class Fu
{
	void show()
	{
		System.out.println("fu show run");
	}
}

class Zi extends Fu
{
	void show()
	{
		System.out.println("zi show run");
	}
}

class ExtendsDemo2
{
	public static void main(String[] args)
	{
		Zi z = new Zi();
		z.show();
	}
}

什么时候使用覆盖?

当对一个类进行子类的扩展时,子类需要保留父类的功能声明。
但是要定义子类中该功能的特有内容时,就是用覆盖操作完成。

class Phone
{
	void call()
	{}
	void show()
	{
		// System.out.println("pic");
		// System.out.println("name");
		System.out.println("number");
	}
}

应用场景
现在手机升级了,加了显示姓名和图片的功能。
但是如果我直接在源代码上修改会增加修改成本,不好。
这时候我们就可以用继承来解决。

class NewPhone extends Phone
{
	void show()
	{
		System.out.println("pic");
		System.out.println("name");
		// System.out.println("number");
		super.show();
	}
}

class PhoneDemo
{
	public static void main(String[] args)
	{
		// Phone p = new Phone();
		// p.show();
		NewPhone p = new NewPhone();
		p.show();
	}
}

子父类中构造函数的继承

在子类构造对象时,发现访问子类构造函数时,父类也运行了。
为什么呢?
原因是:在子类的构造函数中第一行有一个默认的隐式语句---super();

子类的实例化过程:子类中所有的构造函数默认都会访问父类中的空参数的构造函数。

class Fu
{
	Fu()
	{
		System.out.println("fu run");
	}
}
class Zi extends Fu
{
	Zi()
	{
		//super();  //默认的隐式语句.  调用的就是父类中的空参数的构造函数.
		System.out.println("zi run");
	}
}

class ExtendsDemo4
{
	public static void main(String[] args)
	{
		new Zi();
		/*
		结果为:
		fu run
		zi run
		*/
	}
}

还有一种情况

class Fu
{
	Fu()
	{
		System.out.println("fu run");
	}
	Fu(int x)
	{
		System.out.println("fu run...."+x);
	}
}
class Zi extends Fu
{
	Zi()
	{
		//super();  //默认的隐式语句.  调用的就是父类中的空参数的构造函数.
		System.out.println("zi run...");
	}
	Zi(int x)
	{
		System.out.println("zi run...."+x);
	}
}

class ExtendsDemo4
{
	public static void main(String[] args)
	{
		new Zi(4);
		/*
		结果为:
		fu run
		zi run....4
		*/
	}
}

为什么子类实例化的时候要访问父类中的构造函数呢?
那是因为子类继承了父类,获取到了父类中的内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。

所以子类在构造对象时,必须访问父类中的构造函数。
为什么完成这个必须的动作,就子啊子类的构造函数中加了super(). 语句。

如果父类中没有定义空参数构造函数,那么子类的构造函数必须用super明确要调用父类中哪个构造函数。

同时子类构造函数中如果使用this调用了本类构造函数时,
那么super就没有了,因为super和this都只能定义第一行.所以只能有一个。
但是可以保证的是,子类中肯定会有其他的构造函数访问父类的构造函数。

注意:super语句必须要定义在子类构造函数的第一行,因为父类的初始化动作要先完成。

class Fu
{
	Fu()
	{
		super();
		show();
		return;
	}
	void show()
	{
		System.out.println("fu show");
	}
}
class Zi extends Fu
{
	int num = 8;
	Zi()
	{
		//super();  //默认的隐式语句.  调用的就是父类中的空参数的构造函数.
		//-->通过super初始化父类内容时,子类的成员变量并未显示初始化.
		//等super()父类初始化完毕后,才进行子类的成员变量显示初始化.
		//也就是说要先忙完父类那边的事,然后才能忙自己的事.
		System.out.println("zi cons run..."+num);
	}
	void show()
	{
		System.out.println("zi show ..."+num);
	}
}

class ExtendsDemo5
{
	public static void main(String[] args)
	{
		Zi z = new Zi();
		z.show();
		/*
		结果为:
		zi show...0
		zi cons run...8
		zi show...8
		*/
	}
}

一个对象实例化的过程:
Person p = new Person();
1. jvm会去读取指定路径下的Person.class文件,并加载进内存。
并会先加载Person的父类(如果有直接的父类的情况下)。
2. 在堆内存中的开辟空间,分配地址。
3. 并在对象空间中,对对象中的属性进行默认初始化。
4. 调用对应的构造函数进行初始化。
5. 在构造函数中,第一行会先调用父类中的构造函数进行初始化。
6. 父类初始化完毕后,再对子类的属性进行显示初始化。
7. 在进行子类构造函数的特定初始化。
8. 初始化完毕后,将地址赋值给引用变量。

时间: 2024-10-08 03:50:41

Java学习个人备忘录之继承的相关文章

别样JAVA学习(五)继承上

上章我们进行了面向对象的学习, 发现如果定义的几个类中的属性和方法重复, 代码是不是会显得很冗余啊?,有没有一种思想可以简化呢? 有!下面我们来看继承就能解决这个问题 1.继承-概述 继承: 1,提高了代码的复用性 2,让类与类之间产生了关系,也就是多态的特性 注意:千万不要为了获取其它类的功能,简化代码而继承 必须是类与类之间有所属关系才可以继承. Java语言中:java只支持单继承,不支持多继承 因为多继承容易带来安全隐患:当多个父类中定义了相同功能 且功能内容不同时,子类对象不确定运行哪

别样JAVA学习(六)继承下(2.1)Object类equals()

上一节继承下(一)我们进行抽象类.接口以及多态的学习, 接下来大家我们讲点特殊的东西就是object类, 我们一直在说继承,子继承了父,父还有没有父类呢, 为什么这么思考,大家想构造函数的第一行是不是都有 一个隐式的super()语句,它们是不是也都会去访问自己的 父类呢?其实是的,这个父类叫什么呢? 叫做Object类,传说JAVA对象中的上帝,哈哈. 1.定义 所有对象的超类,所有对象的直接后者间接父类. 肯定是所有对象都具备的功能. 随便定义一个类 class Demo{}除了隐式的构造方

别样JAVA学习(六)继承下(2.3)异常下

1.RuntimeException Exception中有一个特殊的子类异常RuntimeException执行时异常. 假设在函数内容抛出该异常,函数上能够不用声明.编译一样通过. 假设在函数上声明了该异常,调用者能够不用进行处理.编译一样通过. 之所以不用在函数上声明,是由于不须要让调用者处理. 当该异常发生,希望程序停止. 由于在执行时,出现了无法继续运算的情况, 希望停止程序后.对代码进行修正. 例: class Person { public void checkName(Strin

JAVA学习笔记--组合与继承

JAVA一个很重要的功能就是代码的可复用性,代码复用可以大大提升编程效率.这里主要介绍两种代码复用方式:组合和继承. 一.组合 组合比较直观,只需在新的类中产生现有类的对象,新的类由现有类的对象组成,因而称之为组合.这种方法只是复用了代码的功能,而不是它的形式. 1 public class Combine{ 2 public static void main(String[] args){ 3 /* 以下两行代码即体现了组合 */ 4 Combine1 com1 = new Combine1(

Java学习个人备忘录之接口

abstract class AbsDemo { abstract void show1(); abstract void show2(); } 当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示-----接口  interface 定义接口使用的关键字不是class,是interface. 对于接口当中常见的成员:而且这些成员都有固定的修饰符1. 全局常量:public static final2. 抽象方法:public abstract 由此得出结论,接口中的成员

java学习笔记6--类的继承、Object类

1.类的继承 一种由已有的类创建新类的机制,是面向对象程序设计的基石之一.通过继承,可以根据已有类来定义新类,新类拥有已有类的所有功能 Java只支持单继承,每个子类只能有一个直接父类,父类是所有子类的公共属性及方法的集合,子类则是父类的特殊化,继承机制可以提高程序的抽象程度,提高代码的可重用性 基类(base class),也称超类(superclass),是被直接或间接继承的类 派生类(derived-class),也称子类 (subclass),继承其他类而得到的类,继承所有祖先的状态和行

Java学习个人备忘录之异常

概述 异常:是在运行时期发生的不正常情况. 在java中用类的形式对不正常情况进行了描述和封装对象. 描述不正常的情况的类,就称为异常类. 以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性. 其实异常就是java通过面向对象的思想将问题封装成了对象. 用异常类对其进行描述.不同的问题用不同的类进行具体的描述. 问题很多,意味着描述的类也很多.将其共性进行向上抽取,形成了异常体系. 最终问题(不正常情况)就分成了两大类 Throwable:无论是error,还

别样JAVA学习(五)继承上(1.1)Object类toString()

接下来说完equals以后,我们学习接下来的toString(), Java又觉得全部对象不光具有比較性, 还能使对象变成字符串被打印. 出现 曾经前面显示的是数组.如今显示的是这个对象所属的类. 紧跟着是这个对象的哈希值,也就是全部的对象都有哈希值(内存地址). 接下来.改动ObjectDemoToString class类 class ObjectDemoToString { public static void main(String[] args) { Demo d1=new Demo(

别样JAVA学习(六)继承下(2.2)Object类toString()

接下来说完equals以后,我们学习接下来的toString(), Java又认为所有对象不光具有比较性, 还能使对象变成字符串被打印. 出现 以前前面显示的是数组,现在显示的是这个对象所属的类, 紧跟着是这个对象的哈希值,也就是所有的对象都有哈希值(内存地址). 接下来,修改ObjectDemoToString class类 class ObjectDemoToString { public static void main(String[] args) { Demo d1=new Demo(