黑马程序员——Java基础——继承(二)

------ Java培训、Android培训、iOS培训、.Net培训 、期待与您交流! -------

实例化:
/**
 * 继承:
 * 子类的实例化过程
 * 子类中的所有的构造函数默认都会访问父类中空参数的构造函数.
 * 因为每一构造函数的第一行都有一条默认的语句super();
 * 
 * 为什么子类实例化的时候要访问父类中的构造函数呢?
 * 那是因为子类继承了父类,获取到了父类中的内容(属性),
 * 所以在使用父类内容之前要先看父类时如何对自己的内容进行初始化的.
 * 
 * p.s.
 * 1.当父类中没有空参数的构造函数时,
 * 子类的构造函数必须通过this或者super语句指定要访问的构造函数.
 * 2.子类构造函数中如果使用this调用了本类构造函数,那么默认的super();就没有了,
 * 因为super和this都只能定义在第一行,所以只能有一个.但是可以保证的是,
 * 子类中肯定会有其他的构造函数访问父类的构造函数.
 * 3.super语句必须要定义在子类构造函数的第一行,因为父类的初始化动作要先完成.
 */
class Fu{
	Fu(){
		super();
		//调用的是子类的show方法,此时其成员变量num还未进行显示初始化
		//该show方法已被子类重写,所以会调用子类的show方法
		show();
		return;
	}
	void show(){
		System.out.println("fu show");
	}
}

class Zi extends Fu{
	int num = 8;
	Zi(){
		super();
		//通过super初始化父类内容时,子类的成员变量并未显示初始化,等super()父
		//类初始化完毕后,才进行子类成员的变量显示初始化
		return;
	}
	void show(){
		System.out.println("zi show" + num);
	}
}

public class ExtendDemo {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();
	}
}
/*总结:
 * 一个对象实例化的过程中,以Person p = new Person();为例:
 * 1.jvm会读取指定路径下的Person.class文件,并加载进内存,并会先加载Person的
 * 父类(如果有直接父类的情况下).
 * 2.在内存中开辟空间,并分配地址.
 * 3.并在对象空间中,对对象的属性进行默认初始化.
 * 4.调用对应的构造函数进行初始化.
 * 5.在构造函数中,第一行会先调用父类中的构造函数进行初始化.
 * 6.父类初始化完毕后,再对子类的属性经行显示初始化.
 * 7.再进行子类构造函数的特定初始化.
 * 8.初始化完毕后,将地址值赋给引用变量.
 */
输出结果:
zi show0
zi show8

final关键字:
/**
 * final关键字
 * final可以修饰类,方法,变量.
 * final修饰的类不可以被继承.
 * final修饰的方法不可以被重写.
 * static修饰的方法不可以被重写.
 * private修饰的方法不可以被重写.
 * 被重写的函数,子类的权限一定要大于父类的权限.
 * 
 * final修饰的变量将变为常量,并且只能被赋值一次.
 * 
 * 为什么要用final修饰变量,其实,在程序中,如果一个数据是固定的.
 * 那么直接使用这个数据就可以了,但是,这种方式阅读性差,所以应该给数据起个名称.
 * 而且这个名称的值不能变化,所以加上final固定.
 * 写法规范:常量所有字母都大写,多个单词,中间用_连接.
 */
//继承的弊端:打破封装性
class Fu1{
	void method(){
	}
}

class Zi1 extends Fu1{
	public static final double PI = 3.14;
	void method(){
		System.out.println(PI);
	}
}

public class FinalDemo {
	public static void main(String[] args) {
		Zi1 z = new Zi1();
		z.method();
	}
}
运行结果:
3.14
抽象类:
package cn.fuxi.chouxiang;
/**
 * 抽象类
 * 抽象:就是将多个事物中共性的,本质的内容抽取出来.
 * 例如:狼和狗共性都是犬科,犬科就是抽象出来的概念.
 * 
 * java中可以定义没有方法体的方法,该方法的具体实现由子类完成,
 * 该方法称为抽象方法,包含抽象方法的类就是抽象类.
 * 
 * 抽象方法的由来:
 * 多个对象都具有相同的功能,当时功能具体有所不同,
 * 那么在抽取的过程中,只抽取了功能定义,并未抽取功能主题,
 * 那么只有功能声明,没有功能主体的方法称为抽象方法.
 * 例如:狼和狗都有吼叫的方法,可是吼叫的内容不一样.所以抽象出来的
 * 犬科虽然有吼叫大功能,但是并不明确吼叫的细节.
 * 
 * 特点:
 * 抽象类和抽象方法必须用abstract关键字来修饰.
 * 抽象方法只有方法声明,没有方法体,定义在抽象类中.
 * 格式:修饰符 abstract 返回值类型 函数名(参数列表);
 * 
 * 抽象类不可以被实例化,也就是不可以用new创建对象.
 * 原因如下:
 * 1.抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例.
 * 列如:犬科是一个抽象的概念,真正存在的是狼和狗.
 * 2.而且抽象类即使创建了对象,调用抽象方法也没有意义.
 * 3.抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后
 * 才可以创建对象,否则该子类也是抽象类.
 */

abstract class Demo{
	abstract void show();
}

class DemoA extends Demo{
	void show(){
		System.out.println("demoa show");
	}
}

class DemoB extends Demo{
	void show(){
		System.out.println("demob show");
	}
}

public class AbstractDemo {
	public static void main(String[] args) {
		DemoA da = new DemoA();
		da.show();
		DemoB db = new DemoB();
		db.show();

	}
}

运行结果:

demoa show
demob show
/**
 * 
需求:
公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
分析:
在这个问题领域中,通过名词提炼法:

程序员:
属性:姓名,工号,薪水。
行为:工作。

经理:
属性:姓名,工号,薪水,奖金。
行为:工作。

程序员和经理不存在着直接继承关系。
但是,程序员和经理却具有共性内容,可以进行抽取,因为他们都是公司的雇员。
可以将程序员和经理进行抽取,建立体系。
 */

//描述雇员
abstract class Empolyee{
	private String name;
	private String id;
	private double pay;
	Empolyee(String name,String id,double pay){
		this.name = name;
		this.id =id;
		this.pay =pay;
	}
	public abstract void work();
}
class Programmer extends Empolyee{
	Programmer(String name,String id, double pay){
		super(name,id,pay);
	}
	public void work(){
		System.out.println("code..");
	}
}
class Manager extends Empolyee{
	private int bonus;
	Manager(String name,String id,double pay,int bonus){
		super(name,id,pay);
		this.bonus =bonus;
	}
	public void work(){
		System.out.println("manage");
	}	
}

public class AbstractDemo2 {
	public static void main(String[] args) {	
	}
}
/*
 * 问题:
 * 1.抽象类中是否有构造函数?
 * 答:有,用于给子类对象初始化.
 * 2.抽象关键字abstract不可以和哪些关键字共存?
 * 答:final,static,private
 * 3.抽象类中可不可以没有抽象方法?
 * 答:可以,很手少见.目的就是不让该类创建对象,AWT适配器对象就是这种类,
 * 通常没有方法体,但是却没有内容.
 */
abstract class Demo1{
	void show1(){}
	void show2(){}
}
/*4.抽象类和一般类区别?
 * 答:
 * 相同点:抽象类和一般类都是用来描述事物的,都在内部定义了成员.
 * 不同点:
 * 		1--一般类有足够的信息描述事物.
 * 			抽象类描述事物的信息有可能不足.
 * 		2--一般类中不能定义抽象方法.
 * 			抽象类中既可以定义抽象方法,又可以定义非抽象方法.
 * 		3--一般类可以被实例化.
 * 			抽象类不可以被实例化.
 * 
 * 5.抽象类一定是个父类吗?
 * 答:是的,因为需呀子类覆盖其方法后才可以对子类实例化.
 */

接口:
ackage cn.fuxi.jiekou;
/**
 *接口:
 *当一个抽象类中所有的方法都是抽象的时候,这时可以将该抽象类用另一种形式
 *和定义表示,这就是接口
 *格式:interface{}
 *
 *接口中的成员修饰符是固定的:
 *成员常量:public static final
 *成员函数:public abstract
 *由此得出结论,接口中的成员都是公共的权限.
 *
 *接口是对外暴露的规则
 *接口是程序的功能拓展.
 *
 *p.s.
 *1.虽然抽象类中的全局变量和抽象方法的修饰符都可以不写,但是
 *这样阅读性很差.所以,最好写上.
 *2.类与类之间是继承关系,类与接口之间是实现关系.
 *3.接口不可以实例化(new),能由实现了接口,并覆盖了接口中
 *所有的抽象方法的子类实例化.否则,这个子类就是抽象类.
 */
interface Demo{
	public static final int NUM=4;
	public abstract void show1();
	public abstract void show2();
}

class DemoImpl implements Demo{
	public void show1(){}
	public void show2(){}
}

class InterfaceDemo {
	public static void main(String[] args) {
		DemoImpl d = new DemoImpl();
		System.out.println(d.NUM);
		System.out.println(DemoImpl.NUM);
		System.out.println(Demo.NUM);
	}
}
运行结果:
4
4
4
package cn.fuxi.jiekou;
/**
 * 接口的出现,将"多继承"通过另一种形式体现出来,即"多实现".
 * 在java中不直接支持多继承,因为会出现调用的不确定性.
 * 所以,java将多继承机制经行改良,在java中变成了多实现,
 * 一个类可以实现多个接口,避免了单继承的局限性.
 */
interface A{
	public void show();
}
interface B{
	public void show();
}
class C{
	public void method(){
		
	}
}

//多实现
class Test implements A,B{
	public void show(){
		System.out.println("Test");
	}
}

class Test2 extends C implements A,B{
	public void show(){
		System.out.println("Test2");
	}
}

public class InterfaceDemo2 {
	public static void main(String[] args) {
		Test t = new Test();
		t.show();
		Test2 t2 = new Test2();
		t2.show();

	}
}

运行结果:
Test
Test2
interface CC{
	void show1();
}

interface DD{
	void show2();
}

//接口与接口之间是继承关系,而且接口可以多继承
interface EE extends CC,DD{
	public void show3();
}

class FF implements EE{
	public void show1(){}
	public void show2(){}
	public void show3(){}
}

public class InterfaceDemo3 {
	public static void main(String[] args) {

	}
}
/*
 *抽象类和接口的异同点:
 *相同点:都是不断向上抽取而来的.
 *不同点:
 *1.抽象类要被继承,而且只能单继承
 *	接口需要被实现,而且可以多实现
 *2.抽象类中可以定义抽象和非抽象方法,子类继承后,可直接使用非抽象方法(无需重写非抽象).
 *	接口中只能定义抽象方法,必须由子类去实现.
 *3.抽象类的继承,是is a关系,定义该体系的基本共性内容.
 *	接口的实现是like a关系.
 */

package cn.fuxi.jiekou;
/**
 * 接口综合案列:
 * 笔记本电脑使用.
 * 为了扩展笔记本的功能,但日后出现什么功能设备不知道.
 * 因此需要定义一个规则,只要日后出现的设备都符号这个规则就可以了.
 * 规则在java中就是接口.
 */
//暴露原则
interface USB{
	public void open();
	public void close();
}
//实现原则
//这些设备和电脑的耦合性降低了
class Upan implements USB{
	public void open(){
		System.out.println("Upan open");
	}
	public void close(){
		System.out.println("Upan close");
	}
}
class USBMouse implements USB{
	public void open(){
		System.out.println("USBMouse open");
	}
	public void close(){
		System.out.println("USBMouse close");
	}
}
public class InterfaceDemo4 {
	public static void main(String[] args) {
		//功能拓展了
		useUSB(new USBMouse());		
	}
	//接口类型的引用,用于接收(指向)接口的子类对象
	public static void useUSB(USB u){
		if(u != null){
			u.open();
			u.close();
		}
	}
}
运行结果:
USBMouse open
USBMouse close




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值