第四周进度报告
这周主要学习Java的一些知识,下面是学习笔记:
- 继承中成员变量访问特点:就近原则
|System.out.println(name);|从局部位置开始开始往上找|
|Sytem.out.println(this.name)|从本类成员变量开始往上找|
|Sytem.out.println(super.name)|从父类成员变量开始往上找|
package Extends;
class Student{
public void eat(){
System.out.println("学生在吃饭");
}
}
class OverseaStudent extends Student{
@Override
public void eat(){
System.out.println("留学生在吃饭");
}
public void lunch(){
this.eat();
super.eat();
}
}
public class ExtensTest {
public static void main(String[] args) {
OverseaStudent os = new OverseaStudent();
os.lunch();
}
}
方法重写
当父类方法中,不能满足子类现在的需求时,我们就需要吧这个方法进行重写
注意:方法重写时上面要加上@Override
方法重写的本质,覆盖了虚方法表中的方法
继承中构造方法的特点
- 父类中构造方法不会被子类继承
- 子类中所有的构造方法Moore你先访问父类中的无参构造,再执行自己
- 子类构造方法的第一行默认都是:super(),不写也存在,且必须在第一行
- 如果想调用父类有参构造,必须手动写super()进行调用
this:理解为一个变量,表示当前方法调用者的地址值
super:代表父类存储空间
多态
多态: 同类型的对象,表现出不同形态
多态的表现形式: 父类类型 对象名称 = 子类对象
多态的前提:
- 有继承关系
- 有父类引用指向子类对象
- 有方法重写
//Person类
package PolymorphicStudy;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(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 show(){
System.out.println(this.getName() + this.getAge());
}
}
//Student类
package PolymorphicStudy;
public class Student extends Person{
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
@Override
public void show(){
System.out.println("学生的信息为:" + this.getName() + ", " + this.getAge());
}
}
//Teacher类
package PolymorphicStudy;
public class Teacher extends Person{
public Teacher() {
}
public Teacher(String name, int age) {
super(name, age);
}
@Override
public void show(){
System.out.println("老师的信息为: " + this.getName() + ", " + this.getAge());
}
}
package PolymorphicStudy;
public class Test1 {
public static void main(String[] args) {
Student s = new Student("张三",18);
Teacher t = new Teacher("李四",40);
register(s);
register(t);
}
//这个方法既能接收老师,又能接收学生
public static void register(Person p){
p.show();
}
}
多态的好处:1. 使用父类型作为参数,可以接收所有子对象 2. 体现多态的扩展性和便利
多态中调用成员的特点
调用成员变量的特点:编译看左边,运行也看左边
调用成员方法的特点:编译看左边,运行看右边
多态的优势
- 在多态形式下,右边对象可以实现解耦合,便于扩展和维护
- 定义方法的时候,使用父类型作为参数,可以接受所有子类对象,体现多态的扩展性和便利
多态的弊端 和 instanceof 用法
package ExtendsTest3;
public class Test1 {
public static void main(String[] args) {
Animal a = new Dog();
//多态不能调用专属属性lookHome
a.eat();
//类型转换判定 instanceof 1.第一种形式
if(a instanceof Dog){
Dog d = (Dog)a;
d.lookHome();
}
else if(a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse();
}
else System.out.println("没有这个类型");
//2.第二种形式 节省代码
if(a instanceof Dog d){
d.lookHome();
}
else if(a instanceof Cat c){
c.catchMouse();
}
else System.out.println("没有这个类型");
}
}
使用其他类的规则
- 使用同一个包中的类时,不需要导包
- 使用java.lang中的类时,不需要导包
- 其他情况都需要导包
- 如果同时使用两个包时的同名类,需要用全类名
- 包的作用?
包就是文件夹,用来管理各种不i同功能的java类
全类名: 包名 + 类名
final
final修饰
方法: 表明该方法是最终方法,不能被重写
类: 表明该类是最终类,不能被继承
变量: 叫做常量,只能被赋值一次
常量
final修饰的变量是基本数据类型:那么变量存储的数据值不能发生改变
final修饰的变量是引用数据类型,那么变量存储的地址值不能发生改变,对象内部的可以改变
权限修饰符
代码块
局部代码块
构造代码块(写在成员位置的代码块,在创建本类对象的时候会先执行构造代码块再执行构造方法,优先于构造方法)
静态代码块:
格式: static{}
特点: 需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景:在类加载的时候,做一些数据初始化的时候使用
package staticTest;
public class Student {
private int age;
private String name;
static {
System.out.println("静态代码块");
}
public Student() {
System.out.println("空参构造");
}
public Student(int age, String name) {
System.out.println("有参构造");
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package staticTest;
public class Test1 {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student(12,"张三");
}
}
抽象类和抽象方法
- 抽象方法:将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样,所以,在父类中不能确认具体的方法体,所以该方法可以定义为抽象方法.
- 抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
抽象方法定义格式:public abstract 返回值类型 方法名(参数列表)
抽象类的定义格式:public abstract class 类名{}
继承抽象类的注意:要重写抽象类中所有抽象方法,或者定义为抽象类
接口
接口就是一种行为,是对行为的抽象
接口的定义和使用
- 接口用关键字interface来定义
public interface 接口名{} - 接口不能实例化
- 接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名{} - 接口的子类(实现类)
要么重写接口中的 所有抽象方法
要么是抽象类
注意
游泳接口
package InterfaceStudy.me;
public interface Swim {
public abstract void swim();
}
类实现接口
public class Dog extends Animal implements Swim{
@Override
public void eat(){
System.out.println("吃骨头");
}
@Override
public void swim(){
System.out.println("狗刨");
}
}
接口中成员的特点
接口和类之间的关系
JDK8以后接口中新增的方法
- 允许在接口中定义默认方法,需要使用关键字default修饰
作用: 解决接口升级的问题
接口中默认方法的定义格式
- 格式:
public default 返回值类型 方法名(参数列表){ }
- 范例:
public default void show(){ }
接口中默认方法的注意事项:
- 默认方法不是抽象方法,所以不强制被重写.但是如果被重写,重写的时候去掉default关键字
- public可以省略,default不能省略
- 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
package me.interfaceStudy;
public interface Inter {
//接口中默认方法
public default void show(){
System.out.println("接口中的show()");
}
public abstract void method();
}
- 允许在接口中定义静态方法,需要用static修饰
接口中静态方法的定义格式
- 格式:
public static 返回值类型 方法名(参数列表){}
- 范例:
public static void show(){ }
接口中静态方法的注意事项:
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
- public可以省略,static不能省略
public interface Inter {
//接口中默认方法
public static void show(){
System.out.println("接口中的静态方法show()");
}
public abstract void method();
}
JDK9新增的方法
接口中私有方法的定义格式: 私有方法为抽象方法和静态方法服务,不能被外界调用
-
格式1:
private 返回值类型 方法名 (参数列表){}
-
范例:
private void show(){}
-
格式1:
private static 返回值类型 方法名 (参数列表){}
-
范例:
private static void method(){}
接口的应用
适配器设计模式
- 当一个接口抽象方法过多,但是我只要使用其中一部分的时候,就可以使用适配器设计模式
- 书写步骤:编写中间类***Adapter,实现对应的接口
对接口中的抽象方法进行空实现,让真正的实现类继承中间类,并重写用的方法,为了避免其他类创建适配器的对象,中间的适配器类用abstract进行修饰
内部类
成员内部类
- 写在成员位置的,属于外部类的成员
- 成员内部可以被一些修饰符所修饰,比如: private,默认,protected,public,public,static
创建内部类对象 Outer.Inter oi = new Outer().new Inter();
静态内部类
局部内部类
匿名内部类
隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置.
匿名内部类的格式new 类名或者接口名() { 重写方法 } ;
格式的细节:包含了继承或实现,方法重写,创建对象,整体就是一个类的子类对象或者接口的实现类
使用场景:当方法的参数是接口或者类时,以接口为例,可以传递这个接口的实现类对象,如果实现类只要使用一次,就可以用匿名内部类简化代码
public class Test1 {
public static void main(String[] args) {
new Swim(){
@Override
public void swim(){
System.out.println("重写swim方法");
}
}.swim();
method(
new Swim(){
@Override
public void swim(){
System.out.println("重写swim方法");
}
}
);
}
public static void method(Swim s){
s.swim();
}
}