Java码农进阶之路~代码块&面向对象特征之继承

一 代码块
1.局部代码块(方法)

书写位置:方法中

作用:限制作用域

2.构造代码块

书写位置:类中 方法外

代码的执行顺序:

①系统调用

②只要创建对象 就会调用

③构造代码块 在 构造方法 之前被调用

作用:当你有方法 需要每一个对象都调用的时候,可以将这个方法在构造代码块中调用(不常用)

3.静态代码块

使用关键词static修饰的代码块

位置:类中方法外

调用顺序:

1.随着类的加载

2.只加载一次

3.在构造代码块之前执行

应用场景:

加载驱动(加载数据库驱动---一个类)

4.同步代码块(多线程部分)
public class Demo01 {
	public static void main(String[] args) {
		//fun1();
		
		Person p1 = new Person();
		p1.name = "发了";
		p1.sayHi();
		
		Person p2 = new Person("啊哦",10);
		p2.sayHi();
		
	}

	public static void fun1() {
//		{
//			// 局部代码块 限制变量的作用域
//			int num = 10;
//		}
//		System.out.println(num);
	}
}

//暴力调试法
//小黄鸭调试法(逻辑调试)
class Person{
	String name;
	int age;
	// 无参 和 有参构造方法
	// 介绍自己方法
	// 吃
	public Person() {
		 name = "奥迪";
		 age = 16; 
		 System.out.println("我是无参的构造方法");
	}
	public Person(String name , int age) {
		this.name = name;
		this.age = age;
		System.out.println("我是有参的构造方法");
	}
	public void sayHi() {
		System.out.println(name + " " + age);
	}
	public void eat() {
		System.out.println("人--吃饭");
	}
	//构造代码块
	{
		System.out.println("我执行了吗?");
	}
	//静态代码块
	static {
		System.out.println("我是静态代码块");
	}
}
其打印结果为

public class Demo02 {
	static {
		System.out.println("我是main方法的静态代码块");
	}
	public static void main(String[] args) {
		System.out.println("我是main方法");
		
		Test test1 = new Test();
		test1.name = "xx";
		
		Test test2 = new Test("dd");
		
	}

}
class Test {
	String name;
	public Test() {
		System.out.println("我是 test类 无参构造方法");
	}
	
	public Test(String name) {
		this.name = name;
		System.out.println("我是 test类 有参构造方法");
	}
	
	{
		System.out.println("我是 test类  构造代码块");
	}
	static {
		System.out.println("我是test类  静态代码块");
	}
}

打印顺序为

先运行main函数,而在此之前需要在方法区将Demo02.class运行,根据之前所说的,在随着类的加载,其静态构造代码块将会率先执行,打印①"我是main方法的静态代码块",之后调用main函数先打印②"我是main方法",随后创建一个对象test,而创建对象之前,又需要先在方法区加载Test类,而类中又有static修饰的静态代码块,所以打印③"我是test类 静态代码块",随之打印④"我是test类 构造代码块",类中代码块执行完毕后,随即创建完无参对象.打印⑤"我是test类 无参构造方法".之后又创建test2对象,同上,打印⑥"我是test类 构造代码块",⑦"我是test类 有参构造方法".



二 面向对象特征之继承

面向对象的特征为:封装,继承,多态

继承:

1.可以进行传递

2.继承的是 属性 和 行为(不是全部)

3.继承 建立 类和类之间的关系

继承的好处:

1.减少代码量

2.提高工作效率

3.增强了类与类之间的关系(让类和类的关系更加紧密)

继承的弊端:

提高内聚:希望一个类中,方法与方法之间联系加强

降低耦合:希望类与类之间减少联系

而继承违反了 低耦合.

什么时候使用继承?

继承:一定要符合 逻辑(比如:苹果 -子类 是 水果 -父类)

如若两个类没有合适的继承关系的话,可以考虑创建并继承一个第三类.

比如 项目经理 和 程序员,没有合适的父子类的逻辑关系,这是可以增加并继承一个员工类.

注意:

1.Java中 只允许 单继承(类与类)(通过接口实现多继承)

Java中 还允许 多层继承(继承链) A->B->C

2.当你想只使用共有方法和属性时,一般选择 使用继承链最顶端的类

3.当你想使用特有方法的时候, 一般选择 使用继承链最末端的类

4.如果一个类没有写继承 ,那么这个类 默认继承 Object类(基类)

三 继承中的构造方法

注意:构造方法是不能继承的

当创建子类对象的时候,为了保证继承的完整性(不管你在创建子类对象的时候,使用的是无参还是有参构造)

系统会默认帮你调用 父类中的 无参 构造方法

public class Demo05 {
	public static void main(String[] args) {
		Son son = new Son();
		System.out.println("-----------------动感光波------------------");
		Son son1 = new Son("小新");
		
	}
}
class Father{
	String name;
	public Father() {
		System.out.println("我是Father类的无参构造方法");
	}
	public Father(String name) {
		this.name = name;
		System.out.println("我是Father类的有参构造方法");
	}
	public void sayHi() {
		System.out.println(name);
	}
}
class Son extends Father{
	public Son() {
		//系统帮你在 构造方法的第一行,写了一句代码
		//如果你不写,系统会默认帮你加上
		super();//调用父类的构造方法
		System.out.println("我是Son类的无参构造方法");
	}
	public Son(String name) {
		super();
		this.name = name;
		System.out.println("我是Son类的有参构造方法");
	}
}

打印的结果是:

再来看这段代码

public class Demo06 {
	public static void main(String[] args) {
		TestB testB = new TestB();
		testB.print();
	}
}
class TestA{
	int num1 = 10;
	int num2 = 20;
	public void fun() {
		System.out.println("我是父类的方法");
	}
}
class TestB extends TestA{
	int num2 = 30;
	public void print() {
		System.out.println(this.num1);
		System.out.println(this.num2);
		//直接调用父类的属性 使用super关键词
		System.out.println(super.num2);
		//super也可以调用父类的方法
		super.fun();
	}
}

super和this

super在子类中代表的是 父类的对象

this在子类中,可以调用子类的属性 和 方法

(当子类中没有这个属性 或者方法的时候,就去父类中寻找,找到就用,没找到就报错)

其打印的是:

如果父类没有无参的构造方法,此时只需要在子类的构造方法中第一行,调用一下父类构造方法

public class Demo07 {
	public static void main(String[] args) {
		Audi audi = new Audi();
	}
}
class Car{
	String name;
//	public Car() {
//		System.out.println("我是Car的无参");
//	}
	public Car(String name) {
		this.name = name;
		System.out.println("我是Car的有参");
	}
}
class Audi extends Car{
	public Audi() {
		//只要你在构造方法的第一行
		//调用一下父类构造方法(无参 有参都行)
		super("双钻");
		System.out.println("我是Audi的无参");
	}
	public Audi(String name) {
		super("四钻");
		this.name = name;
		System.out.println("我是Audi的有参");
	}
}

四 方法重载和重写
方法重载(Overload)(在一个类中进行)
方法重写(Override)(前提:至少两个类 并且还有继承关系)

方法重写相当于对父级的该方法进行升级

重写:跟父类的写法完全一致

书写一个类,都写什么方法?

有参无参构造方法

set/get方法

重写toString方法输出属性

public class Demo08 {
	public static void main(String[] args) {
		TestD testD = new TestD();
		testD.print();
	}
}
class TestC{
	public void print() {
		System.out.println("我是C类的 print方法");
	}
}
class TestD extends TestC{
	public void print() {
		//重写父类的方法时
		//调不调用父类的方法 要根据你的需求而定
		//ios7 siri 只会说英文
		//ios8 siri 英文,中文都能说了
		super.print();
		System.out.println("我是D类的 print方法");
		
		IOS8 ios8 = new IOS8();
		//咱们直接打印对象
		//希望直接把这个类的 属性输出出来
		System.out.println(ios8);
		ios8.siri();
	}
}
class IOS7{
	public void siri() {
		System.out.println("说英文");
	}
}
class IOS8 extends IOS7{
	//注解 标识这个方法是重写父类
	@Override
	public void siri() {
		super.siri();
		System.out.println("说中文");
	}
	public void fun() {
		
	}
	//这个方法 一般用来输出 本类中的属性
	@Override
	public String toString() {
		//调用的是父类的方法
		//打印出来 全类名@16进制的hashcode码
		return "我就想看看属性";
	}
}

五 关键字final

1.可以修饰方法 方法不能被重写

2.修饰类 类不能被继承

3.修饰变量 变量不能修改

final修饰引用数据类型,不能进行重新指向(地址不能修改)

对象中的属性不会影响修改

public class Demo09 {
	public static void main(String[] args) {
//	final int num = 10;
//		num = 20;
	}
}
class TestE{
	//堆内存分配默认值 是无效的默认
//	final修饰成员变量的时候,需要赋值
//	赋值初始值,有三种方式
	//一般使用final会直接定义成静态常量
	//使用类名直接调用 方便
	//常量命名规范 所有字母大写 多单词用下划线分开
//	final int num = 10;
	public static final int MAX_VALUE = 10;
	
	public final void fun() {
		
	}
	
	public TestE() {
		//可以在构造方法中对变量进行赋值
//		num = 10;
	}
	{
		//也可以在构造代码块中进行赋值
//		num = 10;
	}
}
class TestF extends TestE{
//	private void fun() {
//		
//	}
	
}

猜你喜欢

转载自blog.csdn.net/t_kuuga/article/details/80272332