Java -- 面向对象(二)

1、由于面向对象非常的抽象难理解,所以建议各位学习的时候一定要在代码中感受,切忌纸上谈兵,因为放在代码情境里更方便你的直观领悟,但是并不代表理论知识不重要,同样要掌握!!!
2、本篇文章所有的解释性语言都放在代码内部,仔细查看代码,并放到真实的运行环境中亲身感悟,动手跑起来,领悟今日份代码成功运行的快乐。

【承接上篇:面向对象(一)】

六、this关键字

概念

this代表本类对象的一个引用对象。

形式

this.name = name;
3、练习this的用法(两种情况)
3.1 变量名相同时
创建person类
package cn.tedu.thisdemo;

public class Person {
	String name;
	//构造方法
	public Person() {}
	
	public Person(String name) {
		//成员变量name = 局部变量n
		//变量使用时,有个就近原则。所以,等号左右两侧使用的都是局部变量name,左侧根本没找到成员变量
		//name = name;
		
		//1、当成员变量和局部变量同名时,优先使用局部变量;如果想要找到成员变量,通过this关键字调用本类的成员变量
		//2、this代表的是本类的对象的引用。相当于底层帮你写了一行代码:Person this = new Person();
		//3、this能调用的是本类的成员!!!可以是成员【变量】或者【方法】
		this.name = name;
	
	}
}

创建测试类

package cn.tedu.thisdemo;

public class Test_PersonThis {
	//这个类用来测试this --- 变量名相同时
	//总结:当变量名相同时,用this关键字调用成员变量
	public static void main(String[] args) {
		//无参构造对象
		Person p = new Person();
		
		//含参构造对象
		Person p2 = new Person("大白");
		System.out.println(p2.name);
	}
}

控制器显示 : 大白

3.2 构造方法间的调用
	创建Person2类
package cn.tedu.thisdemo;

public class Person2 {
	//创建方法
	public Person2() {
		//2、在无参构造方法中,使用含参构造
		this(13);//必须放在第一行
		System.out.println("无参构造方法");
	}
	
	public Person2(int age) {
		//1、在含参构造方法中,使用 无参构造方法
//		this();
		System.out.println("含参构造" + age);
	}
}

创建测试类
package cn.tedu.thisdemo;

//测试this的使用:构造方法间的调用
public class Test_PersonThis2 {
	public static void main(String[] args) {
		//触发两个构造方法
		//无参构造
		Person2 p = new Person2();
		
		//含参构造
		Person2 p2 = new Person2(18);
	}
}


在这里插入图片描述

七、继承

继承可以说是面向对象中经常用到的,算是重点内容,所以掌握好继承是必须的,要不然分析到多态的时候就会更加的蒙圈。加油!!!

1、概念

1.继承是面向对象最显著的一个特征
2.继承是从已有的类中派生出的新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
3.java继承以使用已存在的类定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性的继承父类/超类/基类
4.这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发成本

特点

1.使用extends关键字,
2.相当于子类把父类的功能复制了一份
3.java只支持单继承;
4.继承可以传递(爷爷,儿子,孙子的关系)
5.不能继承父类的私有成员;
6.继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能的拓展
7.像是is 和 a 的关系

3、入门案例

为验证上述特点,所以设计了三个类进行测试:Grandfather、Father、Son

3.1 Grandfather类
package cn.tedu.extendsdemo;

public class GrandFather {
	int age = 90;
	public void game() {
		System.out.println("下象棋...");
	}
}


3.2 Father类

package cn.tedu.extendsdemo;

public class Father extends GrandFather {
	//5、父类的私有成员,无法被子类继承
	private int s = 20;
	int sum = 10;
	public void show() {
		System.out.println("show()...");
	}
}```


3.3 Son类

```java
package cn.tedu.extendsdemo;

//1、子类想要使用父类的功能,必须发生继承关系
//4、java只支持单继承/单根继承
public class Son extends Father {//7、继承是is a 的关系,是子类和父类发货所能了强制的依赖关系 --- 强耦合(不建议使用)
	//2、当子类继承父类后,相当于把父类的功能复制了一份,可以随时使用父类的功能
	//6、继承的传递性,不仅能用父类的,还能用爷爷类的功能
}


测试类

package cn.tedu.extendsdemo;

//测试继承的入门案例  -- 重点
public class Test_Extends {
	public static void main(String[] args) {
		//创建对象
//		GrandFather gf = new GrandFather();
//		gf.game();
//		System.out.println(gf.age);
		
		//创建父类对象测试
//		Father f = new Father();
//		f.show();//show()...
//		System.out.println(f.sum);//10
		
		//3、创建子类对象测试,能否使用父类功能
		Son son = new Son();
		son.show();//show()...
		System.out.println(son.sum);//10
		son.game();//使用爷爷的属性
		System.out.println(son.age);
	}
}


在这里插入图片描述
子类继承了父类的所有功能;父类继承了爷爷类的所有功能;所以相应的子类也能继承到爷爷的功能;

八、super关键字

1、 作用

1.通过super关键字可以使用父类的内容
2.super代表父类的一个引用对象
3.如果用在构造方法中,必须出现在调用位置的第一条语句!!(类似于this)

九、方法重写override

继承后,子类将拥有了父类的功能;

那么在子类中,可以添加子类特有的功能也可以修改父类的原有功能;

子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数泪飙,完全一致)时,会发生覆盖\复写操作,相当于修改功能;

注意:
父类中的私有方法不能被重写;
子类重写父类方法时,修饰符要大于等于父类修饰符的权限;

十、继承的作用

局部的,成员的,父类的

package cn.tedu.extendsdemo;

//这个类用来测试 继承的 成员变量的使用
public class Test_UseExtend {
	public static void main(String[] args) {
		Son2 son2 = new Son2();
		son2.study();
		System.out.println();
	}
}
//父类
class Father2{
	int count = 5;
	int sum = 30;
}
//子类
class Son2 extends Father2{
	int sum = 20;
	public void study() {
		int sum = 10;
		System.out.println(sum);//10,就近原则
		
		System.out.println(this.sum);//20,使用了成员变量20
//		System.out.println(count);//子类没有,只能使用父类的count -- 简写
		
		//1、使用super关键字,可以在子类中,调用父类的功能
		System.out.println(super.count);//5
		System.out.println(super.sum);//30
		
	}
}


在这里插入图片描述

2、成员方法的使用

继承方法,特有方法,重写方法

package cn.tedu.extendsdemo;

//用来测试继承中成员方法的使用
public class Test_UseExtend2 {
	public static void main(String[] args) {
		Er er = new Er();
		er.eat();//重写前用的是父类的,重写后用的是子类的
		er.sleep();//父类的
		er.coding();//子类特有的
	}
}

class Ba{
	public void eat() {
		System.out.println("重写前,嗯,真香...");
	}
	public void sleep() {
		System.out.println("呼呼呼...");
	}
}
class Er extends Ba{
	
	//3、当需要修改父类的原有功能时,为了不修改源代码,子类可以方法重写
	//方法重写:继承关系 + 子类的方法声明和父类一样
	public void eat() {
//		super.eat();//4、在子类中,测试父类的eat()真的没有影响吗? --真的没有,没有影响父类的源代码
		System.out.println("重写后,吃吃吃...");
	}
	
	//1、子类可以使用父类的所有功能(除了private)
	//2、子类可以使用父类的同时,还可以自己拓展
	public void coding() {
		System.out.println("code...");
	}
}


在这里插入图片描述

总结:
方法重写的意义:当业务发生改变时,我们不能修改源代码,只能发生继承关系后,修改功能;
重写的前提:继承关系 + 子类的方法声明和父类一样;
子类必须有权限重写父类的方法。子类权限 >= 父类权限;
3、构造方法的使用

1.子类创建对象时,默认会去访问父类的无参构造
2.在构造方法的第一行,都有一条默认的语句:super();
3.父类在没有无参构造时,可以用super掉用父类的其他构造

package cn.tedu.extendsdemo;

//这个类用来测试继承中构造方法的使用
public class Test_UseExtends3 {
	public static void main(String[] args) {
		//创建子类对象测试
		//2、子类创建对象时,会触发子类的无参构造,但是第一行隐藏着super()会主动去找父类无参构造
		Sub s = new Sub();//自动匹配无参构造
	}
}
class Baby{
	public Baby(int a) {
		System.out.println("Baby...无参构造");
	}
}
class Sub extends Baby{
	public Sub(){
		//1、默认存在,隐藏不显示,会自动调用父类的无参构造
		//super();//3、目前父类没有无参构造了,会报错
		
		super(8);//4、此时我们只能调用父类的含参构造
		System.out.println("Sub...无参构造方法");
	}
}

在这里插入图片描述

注意:
构造方法不能被继承

拓展

1、this和super的区别
1.this代表本类对象的引用,super代码父类对象的引用
2.this用于区分局部变量和成员变量;
3.super用于区分本类变量和父类变量
4.this成员变量this成员变量()this(参数),代表调用本类的内容;
5.super成员变量super.成员方法()super(参数),代表调用父类内容
6.this和super不可以同时出现在用一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢?

2、重写与重载的区别(overload和override的区别)
1.重载:是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,及参数的数量和参数类型不能完全相同;
2.重写:是存在子父类之间的,子类定义的方法与父类定义的方法具有相同的方法名字,相同的参数列表和相同的返回值类型
3.重写时父类与子类之间多态性的一种表现;
4.重载是一种多态性的一种表现

十一static

1、概念
		是java中的一个关键字
		用于修饰成员(成员变量和成员方法)
2、特点
	1.可以修饰成员变量,成员方法;
	2.随着类的加载而加载,优先于对象加载;
	3.只加载一次机会一直存在不在开辟新的空间;
	4.全局共享,可以被多个对象共享;
	5.可以直接被类名调用;
	6.静态只能调静态,而非静态可以随意调用
	7.static不能和this和super公用,因为有static时可能还没有对象
3、入门案例
package cn.tedu.staticdemo;

//测试 静态 入门案例
public class Test_Static {
	public static void main(String[] args) {
		//测试
		//2、静态资源,优先于对象加载
		StaticDemo.game();//3、静态资源,可以直接被类名调用
		
		StaticDemo demo = new StaticDemo();
		demo.show();
		System.out.println(demo.a);
		
		//4、全局共享,可以被多个对象共享
		demo.name = "jack";
		StaticDemo demo2 = new StaticDemo();
		System.out.println(demo2.name);//已经看到了demo对象修改之后的效果了,确实是共享数据,不然不会看到
		System.out.println(StaticDemo.name);
	}
}
//创建类
class StaticDemo {
	
	//提供静态资源
	//1、static可以修饰成员变量、成员方法
	static String name;
	static public void game() {
		System.out.println("game()...");
	}
	
	//提供普通资源
	int a = 10;
	public void show() {
		System.out.println("show()...");
	}
}


在这里插入图片描述
静态方法内存图
在这里插入图片描述
静态调用关系
只是为了测试调用之间的关系,没有输出语句,如果console空白,不要惊讶!!!

package cn.tedu.staticdemo;

//测试静态的调用关系
public class Test_Static2 {
	public static void main(String[] args) {
		
	}
}
class StaticDemo2{
	//提供普通资源
	int age = 10;
	public void game() {
		//1、普通资源调用静态资源? --可以
		show();
		System.out.println(name);
		System.out.println("game()...");
	}
	
	
	//提供静态资源
	static String name;
	static public void show() {
		//2、静态资源调用普通资源? --不可以,原因:静态只能调用静态,使用的局限性强
		//报错信息:Cannot make a static reference to the non-static method game() from the type StaticDemo2
		//game();
		//System.out.println(age);
		
		System.out.println("下象棋....");
	}
	
}

总结
1.静态资源只能掉静态
2.普通资源可以随意调用

4、静态代码块

对着类加载而加载,并且之被加载一次,一般用于项目有初始化或者加载资源

4.1概述

静态代码块:在类加载时被加载,并且只被加载一次,一般用于项目初始化

构造代码块:在调用构造方法前会被自动调用,每次创建对象都会被调用;

局部代码块:方法里的代码块,方法被调用时才会执行;

静态代码块:static()

位置:在类里方法外;

TODO创建测试类:类中写好静态代码块,构造代码块,构造方法,普通方法里嵌套局部代码块。测试他们呢的执行顺序;

静态-构造代码块-构造方法-局部

测试静态代码块
package cn.tedu.staticdemo;

//测试静态代码块
public class Test_StaticBlock {
	public static void main(String[] args) {
		//创建对象测试
		StaticDeom3 s = new StaticDeom3();
		StaticDeom3 s2 = new StaticDeom3();
		StaticDeom3 s3 = new StaticDeom3();
	}
}
class StaticDeom3{
	//位置:是在类里方法外
	//加载时机:早于对象,是随着类的加载而加载的,而且只会被加载一次来提高效率
	//常用来完成项目的启动或者加载资源
	
	static {
		System.out.println("静态代码块");
	}
	//构造代码块
	{
		System.out.println("构造代码块");
	}
	//构造方法
	public StaticDeom3() {
		System.out.println("构造方法");
	}
}```

控制台显示:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201208201344957.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQ3MzgzNA==,size_16,color_FFFFFF,t_70)
##### 静态变量和实例变量的区别
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加;

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

【下篇预告】

	final
	多态
	异常
	.......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZangChen.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值