JAVA基础(面向对象进阶) —— 包、final、权限修饰符、代码块、抽象类和抽象方法

 通过之前对 JAVA基础 —— 面向对象 以及 JAVA基础 —— 面向对象内存图 的学习。

接下来我们将会进一步学习面向对象进阶的相关知识点。

staticJAVA基础 (面向对象进阶)—— Static
继承JAVA基础 (面向对象进阶)—— 继承
多态JAVA基础 (面向对象进阶)—— 多态
包、final、权限修饰符、代码块、抽象类和抽象方法方法JAVA基础(面向对象进阶) —— 包、final、权限修饰符、代码块、抽象类和抽象方法方法
接口JAVA基础 (面向对象进阶)—— 接口
内部类JAVA基础 (面向对象进阶)—— 内部类

 目录

一、包

二、final关键字

三、权限修饰符

1. 权限修饰符的分类 

2. 权限修饰符的使用规则

 四、代码块

1. 局部代码块

 2. 构造代码块

 3. 静态代码块

 五、抽象类和抽象方法

1. 抽象类和抽象方法的定义

2. 抽象类和抽象方法的定义格式

 3. 抽象类和抽象方法的注意事项

4.  练习: 编写带有抽象类的标准Javabean类

 5. 抽象类和抽象方法的意义


一、包

包就是文件夹,用来管理各种不同功能的Java类,方便后期代码维护。

  • 包名的规则:公司域名反写 + 包的作用,需要全部英文小写,见名知意。

使用其他类的规则:

  • 使用同一个包中的类时,不需要导包
  • 使用java.lang包中的类时,不需要导包。
  • 其他情况都需要导包。
  • 如果同时使用两个包中的同名类,需要用全类名。(全类名:包名 + 类名)

 代码分析:

//com.JavaWork01 和 com.JavaWork02 包中的Teacher类

package com.JavaWork01;
package com.JavaWork02;

public class Teacher {
	private String name;
	private int age;
	
	public Teacher() {}
	public Teacher(String name,int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

//com.JavaLearn 包中的Student 类

package com.JavaLearn;

public class Student {
	private String name;
	private int age;
	
	public Student() {}
	public Student(String name,int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}
//com.JavaLearn 包中的Test测试类


package com.JavaLearn;

import com.JavaWork01.Teacher;

public class Test {
	public static void main(String[] args) {
		// 创建对象
		// 1.使用同一个包中的类不需要导包
		Student s = new Student();
		s.setName("张三");
		s.setAge(23);

		System.out.println(s.getName() + "," + s.getAge());

		// 2.java.lang包中 我们知道有一种:String字符串
		// 此时同样没有导包
		String str = "abc";
		System.out.println(str);

		// 3.使用其他包中类需要导包
		// import com.JavaWork.Teacher;
		Teacher t = new Teacher();

		// 4.同时使用两个包中同名类,需要全类名
		// Teacher t1 = new Teacher();
		// 这样写不知道t2来自于哪个包中的teacher类
		// Teacher t2 = new Teacher();
		com.JavaWork01.Teacher t1 = new com.JavaWork01.Teacher();
		com.JavaWork02.Teacher t2 = new com.JavaWork02.Teacher();
	}
}

二、final关键字

见字知意: 被final关键字修饰的类就是最终类,是不可被改变的。


final可以修饰:

方法表明该方法是最终方法,不能被重写
表明该类是最终类,不能被继承
变量叫做常量,只能被赋值一次,一旦赋值后就不能再被改变
package finalTest;

public class Test {
	public static void main(String[] args) {
		//final修饰变量a
		final int a= 10;
		System.out.println(a);
		//此时修改a值报错
		//被final修饰的a为常量
		a = 20;

       //常量:在实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性。
       //常量的命名规范:
       //单个单词:全部大写
       //多个单词:全部大写,单词之间用下划线隔开
				
	}
	//final修饰父类
	final class Fu {
		//父类方法用final关键字修饰
		public final void show() {
			System.out.println("父类show方法");
		}
	}
	//子类继承父类报错
	//父类是最终类,不能被子类继承
	class Zi extends Fu{
		
		
		@Override
		//子类show方法报错
		//说明被final修饰父类方法不能被子类继承
		public void show() {
			System.out.println("子类show方法");
		}
	}
}

final关键字细节:

final修饰的变量

基本数据类型变量存储的数据值不能发生发生改变。
引用数据类型变量存储的地址值不能发生改变,内部的属性值可以改变。
public class Test {
	public static void main(String[] args) {
	
		final double pai = 3.14;
		//报错!
		//被pai修饰的基本数据类型pai为常量
		//其数据值不能被改变
		double pai = 3.1415;
		
		
		final Student s =new Student("zhangsan",23);
		//被final修饰引用数据类型可以修改数据值
		s.setName("lisi");
		s.setAge(24);
		
		//报错!
		//被final修饰的引用数据类型地址值不能改变
		s = new Student();
		
	}
}

三、权限修饰符

  • 权限修饰符:是用来控制一个成员能够被访问的范围的。
  • 可以修饰成员变量:方法、构造方法、内部类。

1. 权限修饰符的分类 

   有四种范围由小到大为(private < 空着不写 < protected < public

修饰符同一个类中同一个包中其他类不同包下的子类不同包下的无关类
private

空着不写

(默认)

protected
public

2. 权限修饰符的使用规则

实际开发中,一般只用private和public

  • 成员变量私有
  • 方法公开

特例:如果方法中的代码时抽取其他方法中共性代码,这个方法一般也私有。

 四、代码块

1. 局部代码块

作用:提前结束变量的生命周期
最本质特征:节约内存,变量不再使用就立马让其消失,如今使用不大。

 2. 构造代码块

构造代码块就是写在成员位置的代码块,优先于构造方法执行。

此时发现空参构造和带参构造出现重复sysout语句。 (因此我们新增了构造代码块

作用:可以将多个构造方法中重复的代码抽取出来。

执行时机:我们在创建本类对象先执行构造代码块再执行构造方法

当多个构造方法都有重复代码时,我们可以如下操作:

 3. 静态代码块

格式:static{ }

特点:需要通过satic关键字修饰,随着类的加载而加载,并且自动触发,只执行一次

使用场景:在类加载的时候,做一些数据初始化的时候使用。

 五、抽象类和抽象方法

1. 抽象类和抽象方法的定义

  • 抽象方法:将共性的行为(方法)抽取到父类之后。

                         由于每一个子类执行的内容是不一样的。

                         所以,在父类中不能确定具体的方法体。

                         该方法就可以定义为抽象方法。

  • 抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类。
  • 作用:抽取共性时,无法确定方法体,就把方法定义为抽象的;强制让子类按照某种格式重写;抽象方法所在的类,必须是抽象类。

2. 抽象类和抽象方法的定义格式

  • 抽象方法的定义格式:

              public abstract 返回值类型 方法名(参数列表);

  • 抽象类的定义格式:

               public abstract class 类名 { }

例如:

 3. 抽象类和抽象方法的注意事项

  • 抽象类不能实例化(实例化 就是 创建对象)。
  • 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
  • 可以有构造方法
  • 抽象类的子类:① 要么重写抽象类中所有抽象方法;②要么是抽象类。
//父类 Person.java

public abstract class Person {
	private String name;
	private int age;
	
	//可以有构造方法
	//思考:抽象类不能创建对象,那我们要构造方法干什么?
	//答案:当创建子类对象时,给属性进行赋值的。
	public Person() {}
	public Person(String name,int age) {
		this.name = name;
		this.age = age
	}
	
	//有抽象方法的类一定是抽象类
	public abstract void work();
	
	//抽象类中不一定有抽象方法
	public void sleep() {
		System.out.println("睡觉");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}


//子类 Student.java
public class Student extends Person{
	
	public Student() {}
	public Student(String name,String age) {
		super(name,age);
	}
	
	//重写父类方法
	@Override
	public void work() {
		System.out.println("学生的工作是学习");
		
	}
	
}
//测试类

public class Test {
	public static void main(String[] args) {
		// 创建对象
		// 报错: 抽象类不能实例化
		// Person p = new Person();

		Student s = new Student("张三", 23);

		System.out.println(s.getName() + "," + s.getAge());

	}
}

4.  练习: 编写带有抽象类的标准Javabean类

动物属性行为
青蛙frog名字,年龄吃虫子,竭水
狗Dog名字,年龄吃骨头,喝水
山羊Sheep名字,年龄吃,喝水
//父类 Animal.java
public abstract class Animal {
	private String name;
	private int age;

	public Animal() {
	}

	public Animal(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void drink() {
		System.out.println("动物在喝水");
	}

	public abstract void eat();

	/*
	 * public void eat() { 
	 * //此时发现写什么都不对 
	 * //不同动物吃的不一样 
	 * System.out.println("???"); 
	 * }
	 */
}



//Frog.java
public class Frog extends Animal {
	public Frog() {
	}
	public Frog(String name, int age) {
		super(name, age);
	}
	@Override
	public void eat() {
		System.out.println("青蛙在吃虫子");
	}
}


//Dog.java
public class Dog extends Animal {
	public Dog() {
	}
	public Dog(String name, int age) {
		super(name, age);
	}
	@Override
	public void eat() {
		System.out.println("狗吃骨头");
	}
}


//Sheep.java
public class Sheep extends Animal{
	public Sheep() {
	}
	public Sheep(String name, int age) {
		super(name, age);
	}
	@Override
	public void eat() {
		System.out.println("山羊吃草");
	}
}
//Test.java
public class Test {
public static void main(String[] args) {
	
	Frog f = new Frog("小绿",1);
	System.out.println(f.getName() + "," + f.getAge());
	f.drink();
	f.eat();
}
}

运行结果:

 5. 抽象类和抽象方法的意义

  • 疑问:
  •        把子类中共性的内容抽到父类之后
  •        由于方法体不确定,需要定义为抽象。子类使用时需要重写。
  •         那么我们不抽取到父类,直接在子类写不是更节约代码吗?
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hgngy.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值