java基础学习笔记09(代码块、多态、抽象类、final关键词)
第一章:代码块
代码块就是一组通过大括号{}包裹起来的内容。
1.1 初始化块
初始化块定义在类中,方法外的代码块。
实例代码:
public class Person {
private String name;
private int age;
{
System.out.println("Person的初始化块");
}
public Person(){
System.out.println("Person的空参构造器");
}
public Person(String name){
System.out.println("Person的带参构造器");
}
}
public class PersonText {
public static void main(String[] args) {
Person t = new Person();
Person t1 = new Person("张三");
/*输出结果是Person的初始化块
Person的空参构造器
Person的初始化块
Person的带参构造器*/
}
}
代码分析:
- 对于初始化块来说,每次在创建类的对象时都会先运行初始代码块,然后才是对应的构造器;
- 初始化代码块的作用就是将构造器中重复的代码放在初始代码块中运行,一定程度上达到了代码的复用性
- 初始化代码块一般在实际开发中很少用
1.2 静态代码块
是在初始代码块的基础上用static修饰,放在初始代码块上面的代码块。
实例代码:
public class Person {
private String name;
private int age;
static{
System.out.println("Person的静态代码块");
}
{
System.out.println("Person的初始化块");
}
public Person(){
System.out.println("Person的空参构造器");
}
public Person(String name){
System.out.println("Person的带参构造器");
}
}
public class PersonText {
public static void main(String[] args) {
Person t = new Person();
Person t1 = new Person("张三");
/*输出结果是:Person的静态代码块
Person的初始化块
Person的空参构造器
Person的初始化块
Person的带参构造器
*/
}
}
总结:
- 静态代码块会在该类中的内容被调用到了最先执行,而且有且只执行一次。
1.3 练习题
示例代码:
public class Test01 {
public static void main(String[] args) {
new S();
}
}
class F{
static{
System.out.println("F的静态代码块");
}
{
System.out.println("F的初始化块");
}
public F() {
System.out.println("F的空构造器");
}
public F(int age) {
System.out.println("F的带参构造器");
}
public static void info() {
System.out.println("F的静态方法");
}
}
class S extends F{
static{
System.out.println("S的静态代码块");
}
{
System.out.println("S的初始化块");
}
public S() {
System.out.println("S的空构造器");
}
public S(int age) {
System.out.println("S的带参构造器");
}
public static void info() {
System.out.println("S的静态方法");
}
}
输出结果:
F的静态代码块
S的静态代码块
F的初始化块
F的空构造器
S的初始化块
S的空构造器
结论:
- 静态代码块是先于初始化块运行的,所以不管父类还是子类的静态代码块都会先执行;
- 由于子类的空构造器的首行省略了super();所以会先执行父类的构造器,但是执行构造器就一定会执行初始化块,所以先执行F的初始化块;
- 出现父子关系,基本都是先执行父类的,再去执行子类的
1.4 类的加载顺序
类的加载顺序是:
- 加载类中的静态内容
- 创建类的对象之后,加载类中的非静态内容
- 想要启动一个类,该类中必须要有main方法
第二章:多态
2.1 什么是多态?
多态指的是多种形态。一个变量在不同的场景下凸显出来的角色是不同的。
2.2 如何编写多态?
示例代码:
public class Animal {
String name;
String color;
public Animal(){
}
public void eat(){
System.out.println("动物正在吃东西");
}
public void sleep(){
System.out.println("动物正在睡觉");
}
}
public class Bird extends Animal{
int age;
public Bird(){
}
@Override
public void eat(){
System.out.println("鸟儿正在吃");
}
public void fly(){
System.out.println("鸟儿正在飞");
}
}
public class BirdText {
public static void main(String[] args) {
Animal a = new Bird();
a.eat();//多态
a.sleep();
/*输出结果是鸟儿正在飞
动物们正在睡觉
*/
}
}
2.3 多态产生的必要条件
- 一定要发生继承关系
- 子类一定要重写父类的方法
- 创建的子类对象将它赋值给父类变量
- 父类变量去调用重写方法
- 如何看是否发生多态:编译看左边,运行看右边
多态提高了代码的复用性,提高了编程的效率。
第三章:抽象类
3.1 什么是抽象类?
抽象类的产生过程:一致不断的向上抽象,越抽象的内容越不容易理解,越难具象化表现。抽象类本质
还是一个类。类中存在的内容差不多都存在。
定义:修饰符+abstract+class+类名,在修饰类的时候我们加入abstract修饰符修饰,此时类就会变成抽象类。
3.2 抽象类中定义的内容详解
-
抽象类中可以完全定义和类一样的内容(属性、方法、构造器);
-
抽象类中的方法可以是抽象方法也可以是非抽象方法;
-
抽象类就是修饰类的时候前面加上abstract修饰符,此时类就变成抽象类了;
-
被abstract修饰的方法是抽象方法,它没有方法体;
-
抽象类中的抽象方法就是用来被重写的;
-
抽象类中的构造器就是用来被子类调用的而不是用来产生对象的,因为抽象类无法被实例化;
-
抽象类一般情况下我们是用来看懂别人的源码的,继承关系只有一次;
-
当一个类继承了一个抽象方法后,必须要重写抽象类中的全部抽象方法,而且需要查看整个继承链中是否
存在其他抽象方法,如果有也必须要全部重写。
示例代码:
public abstract class Person {
int age;
public Person(){
System.out.println("我是Person");
}
public abstract void sleep();
}
public class Chinese extends Person{
String name;
public Chinese(){
System.out.println("我是Chinese");
}
@Override
public void sleep(){
System.out.println("中国人正在睡觉");
}
}
public class ChineseText {
public static void main(String[] args) {
Person t = new Chinese();
t.sleep();
/*输出结果是我是Person
我是Chinese
中国人正在睡觉
*/
}
}
第四章:final关键词
final的意思是最终的。
4.1 final修饰变量时
当final修饰一个变量时,该变量会变成常量,即变成一个在程序运行期间不可变的量。
实例代码:
public class FinalTest{
static final num = 10;
public static void main(String[] args){
System.out.println(num);
//num = 11;编译报错,final修饰的常量不允许改变
}
}
4.3 final修饰类的时候
示例代码:
public final class MyString {
}//下面代码的定义是错误的
public class SubString extends MyString {
}
总结:
- 用final修饰一个类的时候该类是不可以被继承的,称之为太监类;
- final修饰类就是防止该类被继承的。
4.4 final修饰方法的时候
示例代码:
class F{
public boolean study() {
System.out.println("勤奋、努力");
return true;
}
public final boolean isMan() {
if(study()&&marry()) {
return true;
}
return false;
}
public boolean marry() {
System.out.println("结婚生子");
return true;
}
}
class S extends F{
public boolean study() {
System.out.println("玩着学好。。。");
return true;
}
public boolean marry() {
System.out.println("结婚");
return true;
}
}
总结:
- 用final修饰方法时,该方法是子类不可以被改写的,无法发生多态;
- final重写方法就是为了防止方法的重写