我在千峰培训的日子第十二–十三天------面向对象【继承】

我在千峰培训的日子第十二–十三天------面向对象【继承】

今日感悟

人生最遗憾的莫过于放弃了不该放弃的,固执的坚持了不该坚持的。

老师知识点

一、局部变量跟成员变量

形参和实参
形参:定义在方法中小括号中的变量  例如 public void eat(String name) {}
	形参的作用域同局部变量一样,只在自己的方法中有用
实参:实际传给形参的数值,   例如: Person p = new Person("王策");
成员变量和局部变量区别
区别成员变量局部变量
定义位置定义在类大括号中定义在方法大括号中
作用域哪里有对象地址,哪里就是成员变量的作用域方法对应大括号中
内存储存堆空间中栈空间中
初始化值在没有被构造方法初始化值的情况下,成员变量存储的都是对应数据类型的零值。局部变量在没有被赋值的情况下不能进行除赋值以外的所有操作
生存期成员变量随着对象的创建而出现,随着类的销毁而销毁,JVM通过GC机制管理内存在对应的方法大括号内
零值:基本数据类型:int short byte ----0, long----0L,  char----'\0' 编码集中编号为 0 的字符 nul 不可见字符    			   double----0.0,   float----0.0F,  bolean----false
	引用数据类型: null

GC内存回收机制简介

轮询机制:会在单位时间内来巡查整个内存使用情况,判断当前对象是否有引用地址,如果第一次发现无主内存就标记起来,第二次发现当前内存有人使用,就取消标记,还是无主内存的话就会回收内存
内存引用计数技术:一块内存,有多个引用指向,有几个计数器就会计数几个,如果所有的引用都不在指向当前内存,当前内存明确为无主内存,销毁。

二、继承

继承格式
引入:【基类】--包含了一类事物的基本属性跟基本行为
	 【派生类】--在基类的基础上加入自己独有的属性,数据,特点
【重点】
	对与Java而言,继承使用更多是为了保证数据类型的一致化,数据类型的统一化,和方法的规范化。
//关键字: extends
//格式:
	class Son extends Father {
        
    }
//java中是单继承,一个子类只能可以有一个父类,而一个父类可以有不同的子类
class Father {
	// public 修饰的成员变量
	public String test = "EDG NB!!!";
	
	// private 修饰成员变量【私有化】
	private double btc = 100000000000000000000.01;

	// public 修饰成员方法
	public void test() {
		System.out.println("EDG NB!!!");
	}
	
	private void testPrivate() {
		System.out.println("LPL No.1");
	}
}
class Son extends Father {

}

public class Demo1 {
	public static void main(String[] args) {
		Son son = new Son();
		
		// 子类对象可以使用通过继承得到的父类 pubilc 修饰成员变量 Field
		System.out.println(son.test); 
		
		// 子类对象可以使用通过继承得到的父类 pubilc 修饰成员方法 Method
		son.test();
		
		/*
		 * The field Father.btc is not visible
		 * 子类不可以通过继承得到父类 private 修饰的私有化成员变量 Field
		 */
		// System.out.println(son.btc);
		/*
		 * The method testPrivate() from the type Father is not visible
		 * 子类不可以通过继承得到父类 private 修饰的私有化成员方法 Method
		 */
		// son.testPrivate();
	}
}
super关键字的使用

当父类和子类的属性不同名的时候这时候调用属性时没有影响的,如果同名变量,在子类中访问父类的非私有成员变量时,需要使用super关键字,修饰父类成员变量。

class Fu {
    // Fu中的成员变量。 
    int num = 5; 
}
class Zi extends Fu {
    // Zi中的成员变量 
    int num2 = 6; 
    // Zi中的成员方法 
    public void show() { 
        // 访问父类中的num,
        System.out.println("Fu num="+num); 
        // 继承而来,所以直接访问。 
        // 访问子类中的num2 
        System.out.println("Zi num2="+num2); 
    } 
}
class ExtendDemo02 { 
    public static void main(String[] args) { 
        // 创建子类对象 
        Zi z = new Zi(); 
        // 调用子类中的show方法 
        z.show(); 
    } 
}
演示结果: 
    Fu num = 5 
    Zi num2 = 6
class Zi extends Fu { 
    // Zi中的成员变量 
    int num = 6; 
    public void show() { 
        //访问父类中的num 
        System.out.println("Fu num=" + super.num); 
        //访问子类中的num 
        System.out.println("Zi num=" + this.num);
    } 
}
演示结果: 
    Fu num = 5 
    Zi num = 6
小贴士:Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能 直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员 变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。
方法的重写

当父类和子类的方法不同名的时候这时候调用方法时没有影响的,对象调用方法的时候会现在子类中查看是不是有该方法,如果没有就会执行父类中的方法。

但是当父类中的方法跟子类的方法返回值类型,方法名,参数列表都相同的时候,会出现覆盖效果,也叫复写重写

//@Override 注解---开启重写格式的严格检查,要求子类重写方法声明和父类必须完成一致。如果不一致,直接报错
class Father {
    int age;
    String name;
    
    public void game() {
      System.out.println("麻将");  
    }   
}
class Son {
    int age;
    String name;
    
    @Override
    public void game() {
		System.out.println("LOL WOT PUBG GTA5");
	}
}

public class Demo {
	public static void main(String[] args) {
		Boy boy = new Boy();
		
		/*
		 * 子类可以使用父类的成员方法,但是父类的成员方法不能满足子类实际需求。 
		 * 
		 * 想满足以下情况
		 * 		1. 方法不要多,降低方法的冗余度,保持方法名称一致
		 * 		2. 方法执行的目标不一致,方法体不一致,
		 * 【重写】
		 * 		Override
		 * 		在满足方法声明不变的情况下,降低方法的冗余和记忆压力,通过修改方法体内容
		 * 		完成子类方法的执行目标修改,更加满足子类需求
		 */
		boy.game();
		boy.work();
	}
}
注意 1.子类对象重写父类方法的时候,权限必须大于等于父类的权限
	2.重写方法返回值类型,方法名,参数列表必须完全一样
创建子类对象会执行父类的构造方法
1. 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的
2. 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构 造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代码如下
class Fu { 
    private int n; 
    Fu() {
        System.out.println("Fu()"); 
    } 
}
class Zi extends Fu { 
    Zi() {
        // super(),调用父类构造方法 
        super(); 
        System.out.println("Zi()"); 
    } 
}
public class ExtendsDemo { 
    public static void main (String args[]) { 
        Zi zi = new Zi(); 
    } 
}
输出结果: 
    Fu() 
    Zi()
package com.qfedu.b_extends;

class Yeye {
	public Yeye() {
		System.out.println("爷爷类构造方法");
	}
}

class Fu extends Yeye {
	public Fu() {
		System.out.println("父类构造方法");
	}
}

class Ez extends Fu {
	public Ez() {
		System.out.println("子类构造方法");
	}
}
//执行结果
爷爷类构造方法
父类构造方法
子类构造方法

继承技术点总结
1.在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空 间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构 造方法调用时,一定先调用父类的构造方法。
2. 子类可以通过继承获得父类的非私有化成员 ==>【成员变量 和 成员方法】
3. 子类不可以通过继承获取父类的【私有化成员】 ==> 留一手
4.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZOwCNGt-1636456044095)(C:\Users\wc\AppData\Roaming\Typora\typora-user-images\image-20211108185726445.png)]

三、关键字final

final 最后的,最终的 
可以修饰以下内容
	1. 成员变量
		final修饰成员变量                                              
        【语法要求】                                               
            final修饰的成员变量,必须在定义时初始化,并且一旦赋值,无法修改,为【常量】 ==> 带有名字的常量
	2. 成员方法
        final修饰成员方法                                     
        【语法要求】                                          
            final修饰的成员方法,不能被子类重写, 为最终方法。 --> 一般用于核心方法,涉密方法。           
	3. 局部变量
		final修饰局部变量
		【语法要求】
			一旦被赋值,无法修改
	4. 类
		final修饰类
		【语法要求】
			final修饰的类,不能被其他类继承,没有子类,断子绝孙			
class SingleDog {
	public String name;
	public int age;
}

public class Demo {
	public static void main(String[] args) {
		final SingleDog sd = new SingleDog();
		
		/*
		请问以下操作哪一个正确, 哪一个错误
			1.sd = new SingleDog();
			2.sd.name = "大哥";
			3.sd.age = 12;
		【注意】
			指向地址不可变,指向内容可变!!!
		当前final修饰一个类对象 ==> 引用数据类型变量
			当前引用数据类型变量中存储的数据不可以变  ==> 引用数据类型变量存储的内容不可变 ==> 内容是一个【地址】
			==> 指向地址不可变
			
			SingleDog类的成员变量 name age 没有任何的 final 修饰,存储数据
		 */
		// sd = new SingleDog(); sd 是一个 final 修饰的引用数据类型变量,指向地址不可变,指向内容可变
		sd.name = "大哥";      
		sd.age = 12;         
	}
}

四、多类合作

场景分析:
台式机电脑:
	台式机电脑需要 屏幕和键盘 来组成
	台式机电脑是一个类,屏幕和键盘是否可以看做是另一个类
	成员方法:
		换键盘,换屏幕
		
		键盘类:
	成员变量:
		品牌
		按键个数

屏幕类:
	成员变量:
		品牌
		尺寸
/**
* 把另一个类对象作为参数传递给一个类的对象的创建
*/
public class MainProject {
	public static void main(String[] args) {
		/*
		 * 创建屏幕类对象和键盘类对象【进货】
		 */
		Screen screen = new Screen("AOC", 24);
		Keyboard keyboard = new Keyboard("Cherry", 108);
		
		/*
		 * 组装电脑, 利用键盘类对象和屏幕类对象作为方法的参数,创建Computer类对象。
		 */
		Computer computer = new Computer(keyboard, screen);
		
		
		/*
		 * 看一下电脑的配置,当前电脑的屏幕属性和键盘属性
		 */
		computer.show();
		
		/*
		 * 屏幕出现问题
		 */
		System.out.println("--------------------屏幕出现问题--------------------");
		Screen screen2 = new Screen("华硕", 26);
		/*
		 * 当前Computer类对象 computer 调用setter方法,更换屏幕
		 */
		computer.setScreen(screen2);
		/*
		 * 电脑展示配置
		 */
		computer.show();
		
		/*
		 * 键盘出现问题
		 */
		System.out.println("--------------------键盘出现问题--------------------");
		Keyboard keyboard2 = new Keyboard("IKBC", 87);
		/*
		 * 当前Computer类对象 computer 调用 setter 方法,更换键盘
		 */
		computer.setKeyboard(keyboard2);
		
		/*
		 * 再次展示电脑配置
		 */
		computer.show();
	}
}

五、抽象类

引入:父类中的方法被子类重写,那么父类中的方法主体会被子类里面重新覆盖,就没啥卵用了,只保留方法声明就可以,我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。
/**定义:
抽象方法 : 没有方法体的方法
抽象类:包含抽象方法的类

修饰符 abstract 返回值类型 方法名 (参数列表);*/

class LolHero {
    public void q() {
		System.out.println("Q技能");
	}

	public void w() {
		System.out.println("W技能");
	}

	public void e() {
		System.out.println("E技能");
	}

	public void r() {
		System.out.println("R技能");
	}
}
/**
 * HappyWindBoy 继承 LOLHero 类 这里可以通过继承得到 QWER 方法
 * 
 *
 */
class HappyWindBoy extends LOLHero {
	
}
/**
 * Aphelios 厄斐琉斯 继承LOLHero类,可以通过继承得到 QWER 方法
 * 
 *
 */
class Aphelios extends LOLHero {
	
}
public class Demo1 {
	public static void main(String[] args) {
		HappyWindBoy happyWindBoy = new HappyWindBoy();
		Aphelios aphelios = new Aphelios();
		
		/*
		 * 从目前的 Java 程序运行角度,每一个方法都没有问题,每一个技能都没有问题。
		 * 
		 * 如果英雄联盟每一个英雄的技能都一样,还有什么可玩性???
		 * 		没有可玩性
		 * 
		 * 【要求】
		 * 	目前代码期望子类可以重写父类中的方法,从而满足子类的特征性,非一致性。
		 *  当前代码没有重写父类方法的情况下,语法没有任何的错误!!!【强制重写语法要求】
		 *  
		 * 【强制重写语法要求】
		 * 	子类没有重写/没有实现父类的方法,语法报错。
		 */
		happyWindBoy.q();
		happyWindBoy.w();
		happyWindBoy.e();
		happyWindBoy.r();
		
		System.out.println();
		
		aphelios.q();
		aphelios.w();
		aphelios.e();
		aphelios.r();
		
	}
}
//希望的代码
abstract class LOLHero {
	/*
	 * 期望子类可以重写 q 方法,使用 abstract 关键字修饰 q 方法
	 */
	abstract public void q();

	abstract public void w();

	abstract public void e();

	abstract public void r();
}
/**
 * HappyWindBoy 继承 LOLHero 类 这里可以通过继承得到 QWER 方法
 * @author Anonymous
 *
 */
class HappyWindBoy extends LOLHero {

	@Override
	public void q() {
		System.out.println("斩钢闪");
	}

	@Override
	public void w() {
		System.out.println("风之障壁");
	}

	@Override
	public void e() {
		System.out.println("踏前斩");
	}

	@Override
	public void r() {
		System.out.println("狂风绝息斩");
	}
	
}

/**
 * Aphelios 厄斐琉斯 继承LOLHero类,可以通过继承得到 QWER 方法
 * @author Anonymous
 *
 */
class Aphelios extends LOLHero {

	@Override
	public void q() {
		System.out.println("武器技能");
	}

	@Override
	public void w() {
		System.out.println("月相轮转");
	}

	@Override
	public void e() {
		System.out.println("武器队列系统");
	}

	@Override
	public void r() {
		System.out.println("清辉夜凝");	
	}
	
}
public class Demo1 {
	public static void main(String[] args) {
		HappyWindBoy happyWindBoy = new HappyWindBoy();
		Aphelios aphelios = new Aphelios();
		
		/*
		 * 从目前的 Java 程序运行角度,每一个方法都没有问题,每一个技能都没有问题。
		 * 
		 * 如果英雄联盟每一个英雄的技能都一样,还有什么可玩性???
		 * 		没有可玩性
		 * 
		 * 【要求】
		 * 	目前代码期望子类可以重写父类中的方法,从而满足子类的特征性,非一致性。
		 *  当前代码没有重写父类方法的情况下,语法没有任何的错误!!!【强制重写语法要求】
		 *  
		 * 【强制重写语法要求】
		 * 	子类没有重写/没有实现父类的方法,语法报错。
		 */
		happyWindBoy.q();
		happyWindBoy.w();
		happyWindBoy.e();
		happyWindBoy.r();
		
		System.out.println();
		
		aphelios.q();
		aphelios.w();
		aphelios.e();
		aphelios.r();
		
	}
}
注意:
1.abstract 关键字修饰的方法没有方法体
2.abstract 修饰的方法有且只能定义在 abstract 修饰的类内 或者 interface 接口内
3.一个非 abstract 修饰的类 继承 abstract 类,必须实现在 abstract 类内所有使用 abstract 修饰没有方法体的方法。
4. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义
5.抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
6. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
7.abstract 修饰的方法、对应的类、包括后期学习的接口,都是在制定规则,制定准则。abstract 后期也会作为【承上启下】的功能存在。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值