Java——抽象、接口(黑马个人听课笔记)
1.包
包的概述
包就是文件夹。用来管理各种不同功能的Java类,方便后期代码维护。
- 包名的规则:公司域名反写+包的作用,需要全部英文小写,见名知意。例:com.itheima.domain
使用其他类的规则
- 使用同一个包中的类时,不需要导包。
- 使用java.lang包中的类时,不需要导包。
- 其他情况都需要导包。
- 如果同时使用两个包中的同名类,需要用全类名(包名+类名)。
2.final
可以修饰方法、类、变量。
- 方法:表明该方法是最终方法,不能被重写。
- 类:表明该类是最终类,不能被继承。
- 变量:叫做常量,只能被赋值一次。
常量
实际开发中, 常量一般作为系统的配置信息,方便维护,提高可读性。
常量的命名规范:
- 单个单词:全部大写
- 多个单词:全部大写,单词之间用下划线隔开
细节:
- final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
- final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对象内部的可以改变。
核心:常量记录的数据是不能发生改变的。
3.权限修饰符
- 权限修饰符:是用来控制一个成员能够被访问的范围的。
- 可以修饰成员变量,方法,构造方法,内部类。
权限修饰符的使用规则
实际开发中,一般只用private和public
- 成员变量私有
- 方法公开
特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般有私有。
4.代码块
根据代码块位置分类:
- 局部代码块
- 构造代码块
- 静态代码块
4.1 局部代码块
写在方法里面的一对单独的大括号。
作用:提前结束变量的生命周期。
变量a定义在局部代码块里,只能在局部代码块里有效。
4.2 构造代码块
写在成员位置的代码块。
例:
public class Student {private String name;private int age;//构造代码块://1.写在成员位置的代码块//2.作用:可以把多个构造方法中重复的代码抽取出来//3.执行时机:我们在创建本类对象的时候会先执行构造代码块再执行构造方法//渐渐淘汰了,原因:不够灵活{System.out.println("开始创建对象了");}public Student() {System.out.println("空参构造");}public Student(String name, int age) {System.out.println("有参构造");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 class Test {public static void main(String[] args) {{Student s1 = new Student();Student s2 = new Student("zhangsan",23);}}
}
如果构造方法中有重复代码
4.3 静态代码块
格式:static{}
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次。
使用场景:在类加载的时候,做一些数据初始化的时候使用。
例:
public class Student {private String name;private int age;//执行时机://随着类的加载而加载的,并且只执行一次。static {System.out.println("静态代码块执行了");}public Student() {System.out.println("空参构造");}public Student(String name, int age) {System.out.println("有参构造");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 class Test {public static void main(String[] args) {{Student s1 = new Student();Student s2 = new Student("zhangsan",23);}}
}
总结
5.抽象类
- 抽象方法:将共性的行为(方法)抽取到父类之后。由于每一个子类执行的内容是不一样,所以,在父类中不能确定具体的方法体。该方法就可以定义为抽象方法。
- 抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
抽象类和抽象方法的定义格式
- 抽象方法的定义格式:
public abstract 返回值类型 方法名(参数列表);
- 抽象类的定义格式:
public abstract class 类名{}
抽象类和抽象方法的注意事项
- 抽象类不能实例化(不能创建对象)
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 可以有构造方法(作用:当创建子类对象的时候,给属性进行赋值的。)
- 抽象类的子类:要么重写抽象类中的所有抽象方法,要么子类是抽象类
练习
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 void eat();//此时Alt+enter 可补全abstractpublic abstract void eat();
}
public class Frog extends Animal{public Frog() {}public Frog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("青蛙在吃虫子");}
}
public class Dog extends Animal{public Dog() {}public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("狗吃骨头");}
}
public class Sheep extends Animal {public Sheep() {}public Sheep(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("山羊在吃草");}
}
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();}}
- 抽象类和抽象方法的意义:强制子类必须按照这种格式进行重写,起到一个规范的作用
6.接口
接口就是一种规则,是对行为的抽象。
6.1 接口的定义和使用
- 接口用关键字interface来定义
public interface 接口名 {}
- 接口不能实例化
- 接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名 {}
- 接口的子类(实现类) :要么重写接口中的所有抽象方法,要么子类本身也是抽象类。
注意1:接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2 {}
注意2:实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名1,接口名2{}
练习
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 abstract void eat();
}
public interface Swim {public abstract void swim();
}
public class Rabbit extends Animal{public Rabbit() {}public Rabbit(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("兔子在吃胡萝卜");}
}
public class Frog extends Animal implements Swim{public Frog() {}public Frog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("青蛙在吃虫子");}@Overridepublic void swim() {System.out.println("青蛙在蛙泳");}
}
public class Dog extends Animal implements Swim{public Dog() {}public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("狗吃葡萄");}@Overridepublic void swim() {System.out.println("狗刨");}
}
public class Test {public static void main(String[] args) {//创建青蛙的对象Frog f = new Frog("小青",1);System.out.println(f.getName()+","+f.getAge());f.eat();f.swim();//创建兔子的对象Rabbit r = new Rabbit("小白",2);System.out.println(r.getName()+","+r.getAge());r.eat();}
}
6.2 接口中成员的特点
- 成员变量:只能是常量。默认修饰符:public static final
- 构造方法:没有
- 成员方法:只能是抽象方法。默认修饰符:public abstract
- JDK7以前:接口中只能定义抽象方法。
- JDK8的新特性:接口张可以定义有方法体的方法。
- JDK9的新特性:接口中可以定义私有方法。
6.3 接口和类之间的关系
- 类和类的关系:继承关系,只能单继承,不能多继承,但是可以多层继承
- 类和接口的关系:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系:继承关系,可以单继承,也可以多继承
例1:(多个接口中有重名的方法,重写一次即可)
public interface Inter1 {public abstract void method1();public abstract void method2();public abstract void method3();public abstract void method4();
}
public interface Inter2 {public abstract void method1();public abstract void method2();public abstract void method3();
}
public class InterImpl implements Inter1, Inter2 {@Overridepublic void method1() {}@Overridepublic void method2() {}@Overridepublic void method3() {}@Overridepublic void method4() {}
}
例2: (细节:如果实现类实现了最下面的子接口,那么就需要重写所有的抽象方法)
public interface Inter1 {public abstract void method1();}
public interface Inter2 {public abstract void method2();}
public interface Inter3 extends Inter1,Inter2{public abstract void method3();
}
public class InterImpl implements Inter3 {@Overridepublic void method3() {}@Overridepublic void method1() {}@Overridepublic void method2() {}
}