Java学习笔记13(理解初始化块和abstract)

本文详细介绍了Java中的初始化块,包括非静态代码块和静态代码块的执行顺序及应用场景。同时,讨论了关键字final的用法,指出final变量的特性。接着,深入探讨了抽象类的概念和规则,强调抽象类不能被实例化,以及抽象方法的定义。此外,通过模板方法设计模式的介绍,展示了如何利用抽象类作为子类通用模板进行扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始化块

代码块:
{
xxxx
}

初始化块是对构造器的补充,不能接受任何参数,用于定义类实例化生成的所有对象共有的属性,方法和内容

非静态代码块:没有static修饰的代码块

   1.可以有输出语句。
   2.可以对类的属性声明进行初始化操作。
   3.可以调用静态和非静态的变量或方法。
   4.若有多个非静态的代码块,那么按照从上到下的顺序依
       次执行。
   5.每次创建对象的时候,都会执行一次。且先于构造器执行
public class Person {
	String name;
	//构造方法
	public Person(){
		this.name = "liming";
		System.out.println("执行的构造方法");
	} 
	
	//非静态代码块
	{
		System.out.println("执行的非静态代码块");
	}
	
	public static void main(String[] args) {
		new Person();
	}

}

打印结果:

执行的非静态代码块
执行的构造方法

执行顺序:
1 类的属性默认初始化
2 执行的非静态代码块
3 执行的构造方法

	public static void showAge(){
		System.out.println(age);
	}
	
	
	static int age = 18;
	//静态代码块
	static{
		//这里只能使用静态static修饰的属性和方法
		age = 1;
		showAge();
		System.out.println("执行的静态代码块");
	}//习惯把属性放在后面,代码块写在前面

静态代码块只执行一次。

public class Person {
	String name;
	static int age;
	public Person(){
		this.name = "liming";
		System.out.println("执行的构造方法");
	} 
	
	//非静态代码块
	{
		System.out.println("执行的非静态代码块");
	}
	
	public static void showAge(){
		System.out.println(age);
	}
	
	//静态代码块
	static{
		//这里只能使用静态static修饰的属性和方法
		age = 18;
		showAge();
		System.out.println("执行的静态代码块");
	}
	
	
	public static void main(String[] args) {
		new Person();
		new Person();
	}

}

在这里插入图片描述
发现:
静态代码块只执行一次
非静态代码块,每次new对象的时候重复执行。

静态代码块:用static 修饰的代码块

 1.可以有输出语句。
 2.可以对类的属性声明进行初始化操作。
 3.不可以对非静态的属性初始化。即:不可以调用非静态的属
     性和方法。
4.若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5.静态代码块的执行要先于非静态代码块。
6.静态代码块只执行一次

在实际开发中,静态代码块用的会多一些

这有什么用?
static int age=18;不就可以了吗?,为什么要在静态代码块里面赋值?
因为age 是简单的属性,换一个例子看

新加一个test方法,建立一个匿名类,alt+/ ,方法的重写。
在这里插入图片描述
在这里插入图片描述
这个是匿名类,不能new,没有构造器,所以在静态代码块内初始化!

匿名类(静态代码块的作用)

读代码:看注释!

public class Person {
	String name;
	static int age;
	public Person(){
		this.name = "liming";
		System.out.println("执行的构造方法");
	} 
	
	//非静态代码块
	{
		System.out.println("执行的非静态代码块");
	}
	
	public static void showAge(){
		System.out.println(age);
	}
	
	//静态代码块
	static{
		//这里只能使用静态static修饰的属性和方法
		age = 18;
		showAge();
		System.out.println("执行的静态代码块");
	}
	
	public void test() {
		System.out.println("这是person里的test方法");
	}
	
	public static void main(String[] args) {
//		new Person();
//		new Person();
		
		//没有名称的person的子类。没有类名,就不能构造方法
		Person p = new Person() {
			{
				//用代码块代替构造方法
				super.name = "javer";
			}
			@Override
			public void test() {
				// TODO Auto-generated method stub
				System.out.println("========");
			}
		};
		System.out.println(p.name);
		p.test();//执行的是重写的方法
	}

}

关键字final

final是太监,不能继承。
final

final标记的类不能被继承。提高安全性,提高程序的可读性。
String类、System类、StringBuffer类

final标记的方法不能被子类重写

final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。
static final:全局常量

抽象类

用abstract关键字来修饰一个类时,这个类叫做抽象类;
用abstract来修饰一个方法时,该方法叫做抽象方法。

在这里插入图片描述

抽象类不能被实例化。抽象类是用来作为父类被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。在这里插入图片描述
抽象类一定要有抽象方法,或者提供方法体(不是抽象方法了)
不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法

含有抽象方法的类必须被声明为抽象类。

在这里插入图片描述

代码没有报错,但是不能运行?debug发现main方法写错位置了

源代码:

public abstract class Animal {
	public abstract void test();
	public abstract void move();

	public static void main(String[] args) {
		Dog d = new Dog();
		d.move();
	}
	
	
}

class Dog extends Animal{
	@Override
	public void test() {
		// TODO Auto-generated method stub
		System.out.println("===");
	}
	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("run");
	}
}

也可以新建一个Test.java,用来调用main方法。

练习:
编写一个Employee类,声明为抽象类,包含如下三个属性:name,id,salary。提供必要的构造器和抽象方法:work()。对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。

源代码:


/**
 * 编写一个Employee类,声明为抽象类,
 * 包含如下三个属性:name,id,salary。
 * 提供必要的构造器和抽象方法:work()。
 * 对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。
 * 请使用继承的思想,设计CommonEmployee类和Manager类,
 * 要求类中提供必要的方法进行属性访问。
 * @author jkjkjk
 *
 */
public abstract class Employee {
	public Employee(){
		
	}
	
	int id;
	String name;
	double salary;
	
	//抽象方法work
	public abstract void work();
}

//子类CommonEmployee
class CommonEmployee extends Employee{
	/**
	 * set,get 方法进行属性访问。
	 * @param id
	 * @param name
	 * @param salary
	 */
	public void setCommonEmployee(int id, String name,double salary) {
		//父类的用super
		super.id = id;
		super.name = name;
		super.salary = salary;
	}
	
	public void getCommonEmployee() {
		System.out.println("这是一个普通员工编号"+super.id);
		System.out.println("这是一个普通员工姓名"+super.name);
		System.out.println("这是一个普通员工月薪"+super.salary);
	}
	
	@Override
	public void work() {
		// TODO Auto-generated method stub
		System.out.println("这是父类抽象方法的重写");
	}
}

//子类,manage
class Manage extends Employee{
	double bonus;//子类的成员变量
	
	public void setManage(int id, String name,double salary,double bonus) {
		super.id = id;
		super.name = name;
		super.salary = salary;
		this.bonus = bonus;//本类用this
	}
	
	public void getManage() {
		System.out.println("这是一个普通员工编号"+super.id);
		System.out.println("这是一个普通员工姓名"+super.name);
		System.out.println("这是一个普通员工月薪"+super.salary);
		System.out.println("这是一个普通员工奖金"+this.bonus);
	}
	@Override
	public void work() {
		// TODO Auto-generated method stub
		
	}
}

/**
 * 实例化employee
 * @author jkjkjk
 *
 */
public class TestPerson {
	public static void main(String[] args) {
		CommonEmployee ce = new CommonEmployee();
		ce.work();
		ce.setCommonEmployee(007, "liming", 25000);//要求类中提供必要的方法进行属性访问。
		ce.getCommonEmployee();
	}

}

模板方法设计模式(TemplateMethod)

抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

抽象类是一个大纲,抽象方法就算章节,子类就是内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值