面向对象

面向对象1.0

面向对象的三大特征:继承、封装、多态

1.生活中的面向对象
1.1 面向对象和面向过程对比
烤羊排:
	去店里吃
        1. 找个还不错的店铺
        2. 找坐
        3. 点菜 
        4. 等
        5. 吃
        6. 结账,走
	
	自己做
        1. 羊排 ==> 宁夏 盐滩羊
        2. 腌制 
            洋葱 葱姜蒜水 孜然 盐 拌匀 半个小时
        3. 烤箱预热220度 5分钟
        4. 烤制 撒第一遍孜然 玉米,土豆,芋头 15分钟 (220)
        5. 翻面,撒第二遍孜然 10分钟 (190)
        6. 吃
        7. 收拾东西!!!

牛肉面:
	去店里吃
		1. 找个店铺 重庆 黄记米线 石桥铺地铁站旁边
		2. 排队找坐
		3. 牛肉米线 
		4. 吃
		5. 结账,跑
	
	自己做
		1. 牛肉粒 
		2. 焯水 (料酒,姜, 小葱) 去血沫
		3. 准备炒制使用香料
			桂皮,花椒,麻椒,干辣椒,香叶,八角,小茴香,葱,姜片,蒜
			酱油,老抽,冰糖,黄豆酱
		4. 炒制过程
			1. 热油 葱,姜片
			2. 桂皮,花椒,麻椒,干辣椒,香叶,八角,小茴香
			3. 酱油,老抽
			4. 加牛肉 炒制上色
			5. 加水
			6. 冰糖,黄豆酱
			7. 45分钟起步 (25分钟 用盐调味)
			8. 捡出牛肉保存 滤汤保存
		5. 煮面 上海青
		6. 放上牛肉 鸡精
		7. 吃
		8. 收拾

生活中的面向对象和面向过程:
	面向对象 
		找合适的人,做合适的事
	面向过程
		亲力亲为
1.2 生活中的类和对象
对象
人类马云爸爸,麻花藤,乔布斯,川建国,拜振华
狗类忠犬八公,哮天犬,神犬小七,史努比
猫类Tom,天猫,黑猫警长,虹猫,八九
汽车类马叔叔的奔驰,藤原拓海的AE86
类
	是对于事物的一个描述,有属性描述和行为描述
对象:
	独立的,唯一的,特殊的个体·
2. Java中面向对象
2.1 Java中定义类的格式
格式:
	class 类名 {
		属性描述;
		行为描述;
	}
	注意事项:
		1. 类名要求符合大驼峰命名法!!!
		2. 属性描述 是用于描述当前类对应对象拥有的属性/数据内容
			例如:
				人类 姓名 年龄 性别 ...
				【成员变量 Field】
		3. 行为描述 是用于描述当前类对应对象拥有的能力
			例如:
				人类 吃饭 睡觉 打豆豆
				【成员方法 Method】
class Person {
	/* 属性描述 成员变量 Field */
	// name成员变量用于描述姓名属性,成员变量数据类型 String 字符串类型
	String name;
	
	// age成员变量用于描述年龄属性,成员变量数据类型 int 类型整型
	int age;
	
	// gender成员变量用于描述性别属性,成员变量数据类型 char 类型字符型
	char gender;
	
	/* 行为描述 成员方法 Method */
	/** 
	* 吃饭行为描述,需要的参数是String类型参数 成员方法 Method
	* 
	* @param food 指定的食物
	*/
	public void eat(String food) {
		System.out.println("我中午请你吃 : " + food);
	}
	
	/**
	* 睡觉行为描述,成员方法 Method
	*/
	public void sleep() {
		System.out.println("说出来你可能不行,是床先动手的~~~");
	}
	
	/**
	* 写代码行为描述,成员方法 Method
	*/
	public void coding() {
		System.out.println("键盘敲烂,月薪过程,键盘落灰,该擦了~~~");
	}
}
2.2 创建类对象【new对象】
Scanner sc = new Scanner(System.in);

Scanner 是一个类,Java中工具提供的扫描器类,用于从键盘上扫描获取用户输入的数据。
重点:
	new Scanner(System.in);
	new:
		1. 申请内存【堆区】空间
		2. 清空整个申请空间的所有二进制数据
		
	Scanner(System.in):
		这是一个构造方法 Constructor ,构造方法方法名字和类名一致,固定格式。
	new 构造方法(); 得到一个对象 构造方法名字是【类名】

sc:
	1. Scanner类对象,对象名 sc
	2. sc是一个【引用数据类型】变量

创建对象的格式:
	类名 类对象名 = new 类名();
/*
这里创建了一个Person类对象,对象名 p
p也是一个引用数据类型变量
*/
Person p = new Person();

/*
Person@15db9742
Person : 当前对象的数据类型吗
@ : 在哪里
15db9742 : 十六进制当前对象在内存空间中的地址
*/
System.out.println(p);
2.3 Java中通过类对象操作成员变量
int[] arr = new int[10];
System.out.println(arr.length); 获取数组的容量/长度

arr.length 通过数组名获取当前数组的容量.

格式:
	类对象.成员变量名;	
		取值操作 / 赋值操作
// 通过Person类对象 p操作类内的成员变量
// 通过对象赋值成员变量 
// . 的
p.name = "苟磊";
p.age = 16;
p.gender = '男';

// 通过类对象取值成员变量
System.out.println("Name:" + p.name);
System.out.println("Age:" + p.age);
System.out.println("Gender:" + p.gender);
2.4 Java中通过类对象操作成员方法
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
float num2 = sc.nextFloat();

格式:
	类对象.成员方法(方法对应参数);
	. 的
// 通过Person类对象 p 操作类内的成员方法
p.eat("螺蛳粉+黑蒜+王致和臭豆腐+鲱鱼罐头");
p.sleep();
p.coding();
2.5 类对象内存分析

在这里插入图片描述

3. 构造方法【鸡肋】
3.1 构造方法的格式
public 类名(构造方法所需参数) {
	成员变量初始化语句;
}

特征:
	1. 构造方法名字只能是类名,而且在类内其他成员方法不能使用类名作为方法名。
	2. 构造方法没有返回值!!!

作用: 使用new关键字实际上是在调用构造器
	1. 和new关键字联用,方法名==>类名, 告知new关键字当前申请内存空间需要对应的
	数据类型是什么. 【提供类型】
	2. 初始化当前new关键字申请内存空间中数据,用于初始化操作。
3.2 编译器自动提供无参数构造方法

在这里插入图片描述
在这里插入图片描述

	Java编译器会在程序中未【显式】定义构造方法的情况下,自动补齐一个【无参数构造方法】,方便程序创建当前类对象使用。
3.3 自定义构造方法
// 构造方法定义
// 无参数构造方法 如果在代码中已经明确声明构造方法,
// Java编译器不再提供无参构造方法使用 要求所有类必须有一个无参构造方法备用
public Cat() {
	System.out.println("Cat类无参数构造方法被调用");
}

/**
* 带有String类型参数的构造方法
*
* @param n String类型参数,用于初始化name成员变量
*/ 
public Cat(String n) {
	// name是类内的成员变量
	name = n;
}
	
/**
* 带有三个参数构造方法
*
* @param n String类型用于初始化name成员变量
* @param c String类型用于初始化color成员变量
* @param a int类型用初始化age成员变量
*/
public Cat(String n, String c, int a) {
	name = n;
	color = c;
	age = a;
}
4. 作业
十二生肖:
	1. 一个生肖对应一个文件,Java文件中包含一个生肖类和一个普通类,普通类用于实现main方法
	2. 一个生肖对应三个或者三个以上成员变量,并且十二生肖不可重复
	3. 一个生肖对应三个或者三个以上构造方法,必须有一个无参构造方法
	4. 一个生肖对应三个或者三个以上成员方法,并且十二生肖不可重复
	5. 要求使用三个构造方法进行创建对象操作,并且通过每一个对象,调用对应成员变量,成员方法进行操作。

面向对象 2.0

1. 多类合作
1.1 电脑和维修店
此处有两个类
	电脑类
		属性:
			颜色
			品牌
			GG思密达
		功能:
			写代码
		
	维修店类
		属性:
			店名
			地址
			联系方式
		功能:
			修电脑
/**
* 电脑类
* 
* @author Anonymous
*/
class Computer {
	// 成员变量 Field
	String color;
	String name;
	/**
	* gg表示当前电脑状态,如果为true,电脑有问题无法使用,
	* 否则为false
	*/
	boolean gg;
	
	
	// 构造方法 Constructor
	public Computer() {}
	
	public Computer(String c, String n, boolean g) {
		color = c;
		name = n;
		gg = g;
	}
	
	// 成员方法 Method
	public void coding() {
		// 在执行写代码方法中,需要判断当前电脑状态是否ok
		if (gg) {
			System.out.println("电脑有问题,无法工作,gg");
		} else {
			System.out.pritnln("已每分钟360行飞速写代码~~~");
		}
	}
}
/**
* 修理店类
*
* @author Anonymous
*/
class Factory {
	// 成员变量 Field
	String name;
	String addr; // address
	String tel; // telephone
	
	// 构造方法 Constructor
 	public Factory() {}
	
	public Factory(String n, String a, String t) {
		name = n;
		addr = a;
		tel = t; 
	}
	
	// 成员方法 Method 【重点】
	/*
	成员方法需要完成修电脑功能:
	方法分析:
		public 
			不要问
		返回值类型:
			void 不需要返回值
			
		方法名:
			repair 修理,维修 / fix 修复,修正,修理
		
		形式参数列表:
			功能是修电脑!!!
			这里需要的电脑是由顾客提供的!!!
			当前电脑就是外来数据,也就是【参数】
			参数类型 【要什么,给什么,用什么,拿什么】
			这里需要电脑,电脑我们看作是一个类 Computer类
			
			当前方法所需参数 Computer类的一个对象
			(Computer computer)
			【注意】
				类型名,首字母大写
				变量名/方法名,首字母小写
				希望参数名字可以提供给程序员足够的数据信息
	
	方法声明:
		public void repair(Computer computer)
	*/
	
	/**
	* 修理店 的 维修电脑方法,该方法所需参数是用户提供的电脑类对象
	*
	* @param computer 用户提供的电脑类对象
	*/
	public void repair(Computer computer) throws Exception {
		
		// 判断用户提供的电脑是否有问题,获取电脑的gg成员变量
		if (computer.gg) {
			System.out.println("电脑维修中...... 请稍后");
			
			// 修理电脑,修改电脑的gg属性
			computer.gg = false;
			// 代码暂停一秒钟
			Thread.sleep(1000);
			System.out.println("维修完毕,请付款100W欧元");
		} else {
			System.out.println("WDNMD,检查费1000W欧元");
		}
	}
}
/*
演示整个代码流程,生活逻辑映射
*/
class Demo1 {
	public static void main(String[] args) throws Exception {
		// 购买一台电脑,创建一个电脑类对象
		// 成员变量颜色:黑色 品牌:ThinkPad 是否存在故障:false
		Computer computer = new Computer("黑色", "ThinkPad", false);
		
		// 利用电脑来写代码
		for (int i = 0; i < 10; i++) {
			// 通过电脑类对象执行coding方法
			computer.coding();
			Thread.sleep(500);
		// }
		
		System.out.println("脾气暴躁,电脑一拳,GG");
		// 电脑目前出现问题,当前电脑对象属性 gg ==> true
		computer.gg = true;
		
		// 目前没有修理店,这里需要创建修理店类对象
		Factory factory = new Factory();
		
		// 通过Factory类对象赋值当前属性
		factory.name = "真黑电脑专修技术学院";
		factory.addr = "美国白宫";
		factory.tel = "138XXXXXXXX";
		
		// 通过修理店对象调用repair方法,修理电脑,修理
		// 方法所需参数是Computer类对象 【要什么,给什么】
		factory.repair(computer);
		
		for (int i = 0; i < 10; i++) {
			// 通过电脑类对象执行coding方法
			computer.coding();
			Thread.sleep(500);
		}
	}
}
1.2 电脑,键盘和屏幕
电脑看做是一个类
	成员变量:
		屏幕
		键盘

屏幕看做是一个类
	成员变量:
		尺寸,品牌
	
键盘看做是一个类
	成员变量:
		按键个数,品牌
/**
* 键盘类
*
* @author Anonymous
*/
class Keyboard {
	// 成员变量 Field
	String name;
	int keyCount;
	
	// 构造方法 Constructor
	public Keyboard() {}
	
	public Keyboard(String n, int k) {
		name = n;
		keyCount = k;
	}
}
/**
* 屏幕类
*
* @author Anonymous
*/
class Screen {
	// 成员变量 Field
	String name;
	float size;
	
	// 构造方法 Constructor
	public Screen() {}
	
	public Screen(String n, float s) {
		name = n;
		size = s;
	}
}
/**
* 电脑类
*
* @author Anonymous
*/
class Computer {
	/*
	成员变量:
		电脑是由键盘和屏幕组装而成,在电脑中
		需要有两个类的类对象。键盘类和屏幕类应该
		是电脑类的两个成员变量。
	多类合作:
		一个类中的成员变量是其他类的对象。
	*/
	/*
	屏幕类对象作为Computer类的成员变量 Field
	*/
	Screen screen;
	/*
	键盘类对象作为Computer类的成员变量 Field
	*/
	Keyboard keyboard;
	
	// 构造方法 Constructor
	public Computer() {}
	
	/**
	* 电脑类构造方法,所需要参数是键盘类对象和屏幕类对象
	*
	* @param s Screen屏幕类对象
	* @param k Keyboard键盘类对象
	*/
	public Computer(Screen s, Keyboard k) {
		screen = s;
		keyboard = k;
	}
	
	/**
	* 展示当前电脑的配置
	*/
	public void show() {
		// 展示屏幕的配置
		System.out.println("屏幕配置 品牌:" + screen.name + " 尺寸:" + screen.size);
		// 展示键盘的配置
		System.out.println("键盘配置 品牌:" + keyboard.name + " 按键个数:" + keyboard.keyCount);
	}
}
class Demo2 {
	public static void main(String[] args) {
		// 进货 创建屏幕类对象和键盘类对象
		Screen screen = new Screen("BOE", 15.6F);
		Keyboard keyboard = new Keyboard("Flico", 87);
		
		// 组装电脑 创建Computer类对象
		Computer computer = new Computer(screen, keyboard);
		
		// 电脑类对象,调用show方法,完成配置信息展示
		computer.show();
		
		System.out.println();
		
		// 换键盘 这里需要一个新的键盘类对象
		Keyboard keyboard2 = new Keyboard("IKBC C87", 104);
		// 通过电脑类对象,操作成员变量Keyboard,更换键盘类对象
		computer.keyboard = keyboard2;
		
		computer.show();
		
		System.out.println();
		
		// 换屏幕,这里需要一个新的屏幕类对象
		Screen screen2 = new Screen("Samsung", 88F);
		// 通过电脑类对象,更换成员变量Screen
		computer.screen = screen2;
		
		computer.show();
	}
}
2. 面向对象三大特征之封装
2.1 封装概念
我们的程序设计要追求高内聚,低耦合。高内聚是指内部数据操作细节自己完成,不允许外部干涉;低耦合是指仅暴露少量的方法给外部使用

封装:(数据的隐藏)通常,应直接禁止访问一个对象中数据的实际表示,而操作借口来访问,这称为信息隐藏

简单理解就是不能直接操作数据,而是通过setter和getter方法操作
一段代码,使用三遍,封装成一个方法
一堆方法,使用三遍,封装成一个类
一个类,使用三遍,完成对应的标准文档
一个文档,使用三遍,发一篇博客
2.2 Java封装语法 JavaBean规范
Java中对于【实体类】的封装规范要求
	1. 成员变量全部私有化!!!
	2. 当前类内必须有一个无参数构造方法
	3. 【重点】 提供对应的当前成员变量的Setter和Getter方法
2.2.1 实体类
对应的就是在生活中,真实存在的类。
	人类,汽车类,电脑类...
2.2.2 私有化,权限修饰符
private 私有化
	1. private修饰的成员变量,有且只允许类内使用,类外无法直接使用。
	2. private还可以修饰成员方法,修饰的成员方法有且只允许类内使用,类外也不能用
	3. private修饰构造方法,有且只允许类内使用,后期需要讲解的【单例】设计模式。
	
public 公开的
	随便用,只要拥有当前类对象或者其他方式,都可以直接使用类内public修饰的成员方法,成员变量。
2.2.3 Setter和Getter方法
Setter方法
	功能: 给予当前私有化成员变量赋值操作。
	格式:
		public void set成员变量名(对应当前成员变量数据类型参数) {
			成员变量赋值语句
		}
	例如:
		private String name; 
		完成对应Setter方法
		public void setName(String n) {
			name = n;
		}

Getter方法:
	功能: 获取当前私有化成员变量对应数据
	格式:
		public 对应成员变量的数据类型返回值 get成员变量名() {
			return 目标成员变量;
		}
	例如:
		private String name;
		完成对应Getter方法
		public String getName() {
			return name;
		}
2.2.4 代码案例
class Person {
	// 成员变量 
	// 使用private修饰的成员变量,当前成员变量有且只允许类内使用
	private String name;
	private int age;
	private char gender;
	private boolean married;
	
	public Person() {}
	
	// 完成name 成员变量的Setter方法
	public void setName(String n) {
		name = n;
	}
	
	// 完成 name 成员变量的Getter方法
	public String getName() {
		return name;
	}
	
	public void setAge(int a) {
		age = a;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setGender(char g) {
		gender = g;
	}
	
	public char getGender() {
		return gender;
	}
	
	public void setMarried(boolean m) {
		married = m;
	} 
	
	/*
	【注意】boolean 成员变量getter方法 使用is开头
	*/
	public boolean isMarried() {
		return married;
	}
}

class Demo3 {
	public static void main(String[] args) {
		Person p = new Person();
		
		// p.name = "小明";
		p.setName("小明");
		p.setAge(16);
		p.setGender('男');
		p.setMarried(false);
		
		System.out.println("姓名:" + p.getName() + " 年龄:" + p.getAge() + " 性别:"
		+ p.getGender() + " 婚否:" + p.isMarried());
	}
}
3. this关键字【贼鸡肋】
3.1 this关键字是什么
this关键字
	表示执行当前方法的类对象,或者是 new + 构造方法创建的类对象
class Pig {
	public Pig() {
		System.out.println("Constructor this : " + this);
	}
	
	public void test() {
		System.out.println("test method this : " + this);
	} 
}


class Demo5 {
	public static void main(String[] args) {
		/*
		原则:
			在任何一个开发语言中,如果出现了两个对象
			地址是一致的,表示这里两个对象是同一个对象
		
		this关键字:
			1. 表示调用当前方法的类对象
			2. 也可以是new + 构造方法创建的类对象
		*/
		Pig p = new Pig();
		System.out.println("Pig Object : " + p);
		
		p.test();
	}
}
Result:
	Constructor this : Pig@15db9742
	Pig Object : Pig@15db9742
	test method this : Pig@15db9742
3.2 this关键字目前解决的问题
class Dog {
	private String name;
	private int age;
	
	public Dog() {}
	
	public Dog(String name, int age) {
		/* 
		赋值号左侧的name应该是成员变量name,但是目前
		情况下无法进行明确的区分,会导致就近原则问题
		
		this.成员变量名字 可以明确告知编译器,这里使用的是成员变量,
		而不是和成员变量重名冲突的方法参数变量
		*/
		this.name = name;
		this.age = age;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
}

class Demo4 {
	public static void main(String[] args) {
		Dog dog = new Dog("旺财", 999);
		
		dog.setName("牛头梗");
		dog.setAge(666);
		
		System.out.println("姓名:" + dog.getName() + " 年龄:" + dog.getAge());
	}
}

面向对象 3.0

1. 面向对象之继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

extends的意思是“拓展”,子类是父类的拓展

java中类只有单继承,没有多继承

继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用extends关键字表示

子类和父类之间,从意义上讲应该具有“is a”的关系
1.1 生活中的继承
师承
龙生龙,凤生凤,老鼠的儿子会打洞

LOL
	所有的英雄都有哪些属性?
	血量,魔法值,攻击力,法术强度,攻击速度....
	在游戏开发中,会将统一的属性归纳到一个类中,让其他英雄类继承使用,可以节约代码量,提高开发效率。
1.2 Java中的继承
关键字:
	extends 继承使用的关键字

格式:
	class A extends B {
		
	}
	A类是B类的一个子类
	B类是A类的【唯一】父类,【Java是一门单继承语言】
package com.qfedu.a_extends;

/*
 * Alt + / 自动补齐
 * Ctrl + 1 快速修复 很多功能!!!
 */

class Father {
	public String job;
	
	private String test;
	
	public void work() {
		System.out.println("我父亲是一个教师");
	}
	
	private void testPrivate() {
		System.out.println("父类私有化方法");
	}
}

/*
 * Son类是Father类的一个子类
 * Father类是Son类的唯一父类
 */
class Son extends Father {
	public String name;
	
	public void game() {
		System.out.println("lol 王者 原神 三蹦子 300");
	}
}	

public class Demo1 {
	public static void main(String[] args) {
		Son son = new Son();
		Father father = new Father();
		
		// 通过Father类对象调用父类成员变量和成员方法
		father.job = "教师";
		father.work();
		
		// 通过Son类对象调用Son类自己的成员变量和成员方法
		son.name = "小红";
		son.game();
		
		/*
		 *  通过Son类对象调用继承得到的父类成员变量和成员方法
		 *  
		 *  Eclipse中
		 *  1. 绿色空心圆是public修饰成员变量
		 *  2. 绿色实心圆是public修饰成员方法
		 */
		son.job = "医生";
		son.work();
		
		System.out.println("Name:" + son.name + " Job:" + son.job);
		
		// The field Father.test is not visible
		// Father类的成员变量test不能被访问,因为private修饰
		// son.test = "测试";
		
		// The method testPrivate() from the type Father is not visible
		// Father类内的成员方法testPrivate()是不能被访问的,因为private修饰
		// son.testPrivate();
	}
}
1.3 继承基本要求
子类继承父类:
	1. 可以通过继承得到父类的非私有化成员
	2. 不可以通过继承得到父类的私有化成员

在这里插入图片描述

1.4 继承问题
1.4.1 父类和子类同名成员变量
package com.qfedu.a_extends;

class BigBush {
	public String name = "老王";
}

class SmallBush extends BigBush {
	public String name = "小王";
	
	public void test() {
		/*
		 * super关键字是可以在子类中明确告知编译器这里调用的是父类
		 * 成员变量或者成员方法。
		 */
		System.out.println("就近原则  : " + name);
		System.out.println("super明确调用父类同名成员变量  : " + super.name);
	}
}

public class Demo3 {
	public static void main(String[] args) {
		
		SmallBush smallBush = new SmallBush();
		System.out.println(smallBush.name);
		smallBush.test();
	}
}

1.4.2 父类方法继承给子类使用,不符合要求
父类方法可以继承给子类使用,但是子类使用不符合子类的实际情况,需要想办法解决!!!
2. 重写
2.1 重写解决的问题
重写是修改当前子类继承父类的方法体,让子类执行当前方法可以满足子类的自有情况。 
并且并没有增加程序员开发压力。子类重写父类方法的【方法声明】一模一样!!!   
2.2 重写问题总结
1. @Override 是注解,用于开启当前编译器严格重写格式检查,要求子类重写父类方法,方法声明完全一致!!!
	权限修饰符,返回值类型,返回名,和形式参数列表顺序,参数类型,个数

2. @Override可以不写,但是依然可以保存重写状态。如果子类方法和父类方法声明不同,这里不再是重写方法

3. 重写是修改子类方法体内容,让方法可以更好的满足子类要求。
3. 强制重写需求 abstract
3.1 强制重写分析
【期望】                               
	这里存在一定的重写期望,让子类方法更加适合子类的情况。        
                                   
【语法层面约束】                           
	是否可以子类未重写父类方法,语法报错!!!              
                                   
【错误前置】                             
		原本是在代码运行阶段出现的错误,或者不符合业务要求情况下  
		通过语法约束在代码编译阶段进行提示报错。          
3.2 abstract 关键字 【重点】
abstract修饰的方法,子类要求强制重写/实现
package com.qfedu.b;

/*
实现:
	abstract修饰父类中子类需要强制重写方法

报错:
	Abstract methods do not specify a body
	abstract修饰的方法不能有方法体

解决问题:
	Ctrl + 1 快速修复
	选择:
		Remove method body

报错:
	The abstract method Q in type LOLHero can only be defined by an abstract class
		在LOLHero类内的abstract方法Q有且只能定义在使用abstract修饰的类内
	
	The type LOLHero must be an abstract class to define abstract methods
		LOLHero类必须是一个abstract修饰的类,才可以定义abstract修饰的方法
解决问题:
	Ctrl + 1 快速修复
	选项:
		Make type 'LOLHero' abstract
		
报错:
	The type Zed must implement the inherited abstract method LOLHero.Q()
		Zed类必须实现继承得到的LOLHero类内abstract方法Q();
解决问题:
	Ctrl + 1 快速修复 eclipse语法  idea Alt+enter
	选项:
		Add unimplemented methods
		添加未实现的方法
 */

abstract class LOLHero {
	abstract public void Q();
	
	abstract public void W();
	
	abstract public void E();
	
	abstract public void R();
}

/*
 * 【期望】
 * 这里存在一定的重写期望,让子类方法更加适合子类的情况。
 * 
 * 【语法层面约束】
 * 是否可以子类未重写父类方法,语法报错!!!
 * 
 * 【错误前置】
 * 		原本是在代码运行阶段出现的错误,或者不符合业务要求情况下
 * 		通过语法约束在代码编译阶段进行提示报错。
 */
class Zed 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("禁奥义!瞬狱影杀阵");
	}
}

class Jax 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) {
		
		Zed zed = new Zed();
		
		zed.Q();
		zed.W();
		zed.E();
		zed.R();
		
		System.out.println();
		
		Jax jax = new Jax();
		
		jax.E();
		jax.Q();
		jax.W();
		jax.R();
	}
}
3.3 abstract使用注意事项
1. abstract修饰的方法没有方法体
2. abstract修饰的方法有且只能定义在abstract修饰的类内或者【interface接口】
3. 一个普通类继承abstract类,必须实现类内的所有abstract方法
	承上启下:
		interface Servlet
			abstract class GenricServlet
				abstract class HttpServlet
					
4. abstract类是否可以拥有自己的类对象?new 一个abstract类对象
	abtract修饰的类内有可能存在abstract修饰的方法,abstract方法没有方法体。如果abstract修饰类存在对象,无法执行没有方法体的abstract方法
4. final关键字和super关键字
4.1 final基本语法
修饰成员变量
	1. 定义时必须初始化
	2. 一旦赋值无法修改,带有名字的常量
	
修饰成员方法
	为最终方法,不能被子类重写,一般用于安全考虑

修饰局部变量
	一旦被赋值,无法修改
	
修饰类
	不能被继承,没有子类【断子绝孙】
	Java中 String类就是一个final修饰类
4.2 final面试题
class Person {
    String name;
    int age;
}

main() {
    final Person p = new Person();
    
    p.name = "小明";
    p.age = 16;
    p = new Person();
}

/*
p.name = "小明";
p.age = 16; 
	正确
	
p = new Person();
	错误
	final修饰的是Person类对象 p 。p是一个引用数据类型变量,当前p变量中保存的数据不可以发生改变。【指向不可变】
	Person类内成员变量name age并没有使用final修饰,依然可以修改。
	【指向不可能,指向内容可以变】

生活中的案例:
	房本地址不可以变,但是房子装修随便你
*/
4.3 super关键字

在这里插入图片描述

5. 局部变量和成员变量
5.1 局部变量案例
for (int i = 1; i < 10; i++) {

}

for (int i = 1; i < 10; i++) {

}

以上两个i都是有效范围在for循环以内,超出for循环,无效!!!

for (int i = 0; i < 10; i++) {
	if (i == 5) {
		int num = 10;
	}
	
	Sout(num);
}
num无法使用,因为num的有效范围有且只是在if分支结构中

for (int i = 0; i < 10; i++) {
	for (int j = 0; j < 10; j++) {
		for (int k = 0; k < 10; k++) {
			Sout(i);
			Sout(j);
			Sout(k);
		}
		
		Sout(i);
		Sout(j);
	}
	
	Sout(i);
}

main() {
	int num = 0;
	
	test(num);
}


test(int num) {
	num = 10;
}
5.2 成员变量和局部变量对比
定义位置
	成员变量:
		在class大括号或者interface大括号以内,其他大括号之外
	局部变量:
		方法以内,代码块以内

作用
	成员变量:
		用于描述当前类拥有的属性
	局部变量:
		用于代码运行过程中,对于数据的存储和计算操作。

初始化
	成员变量:
		在没有被赋值,或者被构造方法初始化的情况下,成员变量是对应当前数据类型
		的"零"值
	局部变量:
		Java中局部变量未初始化,不能使用,避免"野值"问题

作用域
	成员变量:	
		谁持有当前类对象空间地址,成员变量就在哪里。
	局部变量:
		有且只能是当前大括号范围以内,超出范围无法使用

生存期
	成员变量:
		从对象创建开始,到当前对象被销毁结束。
	局部变量:
		有且只能是当前大括号范围以内,超出范围被销毁
【补充知识点 "零"值】
"零"值 当前数据对应内存空间,全部二进制为都是0
对外数据效果会根据数据类型不同存在不同的情况
	byte short int 0
	long 0L
	float 0.0F
	double 0.0
	boolean false
	char '\0' ==> nul 不可见字符
	引用数据类型 null
【补充知识点 内存垃圾回收简单模型】

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值