0
点赞
收藏
分享

微信扫一扫

JavaSE_06_面向对象

西曲风 2022-05-02 阅读 35

目录


本文承接这篇文章→JavaSE_04_类和对象继续学习面向对象特性

  • 不写权限访问修饰符,就是包访问权限,在当前包内部可见,只在同级目录下可见,不包含子包

  • 包就是文件夹,项目中的包在本地操作系统中就是文件夹;

  • 要创建多级目录,不同包之间用.操作符分隔;

  • 类名的全名称是包名.类名,包存在的意义是解决类的重名问题;

  • import语句只能导入某个包中具体某一个类;

  • 若要将整个包下的类按需加载,例如import java.util.*,则不需要一个一个导入java.util包中的类,但是一般不推荐这种写法,因为可能会造成歧义:

  • import java.util.*;
    import java.sql.*;
    //上述两个包中都有Date类,在使用Date类时,编译器不知道Date类来自于哪个包
    
  • 解决办法:

    1.使用类的全名称:java.tuil.Datejava.sql.Date

    2.在导入时明确指定Date来自于哪个包

静态导入(不推荐)
//导入一个类下的所有静态方法和属性
import static java.lang.System.*;

//在类中就可以使用out.println()
常见系统包
java.lang:JDK的基础类(System,String,Object, JDK1.1之后这个包下的所有类自动导入
java.lang.reflect:反射开发包
java.util:工具包(集合类都在这个包下,Arrays,LinkedList,HashMap)
java.io:I/O开发包,文件的读取和写入
java.net:网络开发用到的包,Socket
java.sql:数据库开发用到的包

封装

保护性、易用性

方法重载:在同一个类中,方法名称相同,参数列表不同,与返回值类型无关的方法。


继承

减少代码冗余

代码能跑起来是第一步,还要进行CodeReview,避免出现重复代码。在设计模式中进行代码优化。

public class Animal{
    String name;
    public void eat(){
        //TODO
    }
}
public class Dog extends Animal{
    //Animal中的name和eat()在Dog中都有
}

继承的规则

  • 继承的父子类之间必须是一个包含另一个的关系

  • Java中只有单继承,一个子类只能使用extends继承一个父类,可以多层继承。

    class Animal{}
    class Dog extends Animal{}
    class Labuladuo extends Dog{}
    //继承树
    
  • 子类会继承父类的所有属性和方法

  • 显示继承:父类中public修饰的属性和方法可以在子类中直接使用;

  • 隐式继承:父类中private修饰的属性和方法,子类也继承了这些属性和方法,但是无法直接使用。

    class Father{
        private int password;
     	public int getter(){
            return password;
        }
    }
    class Child extends Father{
        //子类对象能通过调用getter()访问password
    }
    
protected

不同包具有继承关系的类,父类的属性和方法在子类的内部是可见的,出了子类,就不可见了。

//protected权限的属性在子类中的用法 04_28

//protected权限  > (defaulted)包访问权限,对于包权限可见的范围,protected权限一定包含。
//protected的可见范围 : 同一个包(指的是同一个级别的包:同级目录,不包括子包)下没有关系的类之间、不同包有继承关系的类之间
this

要产生一个子类对象,默认先产生父类对象。

存在继承时,先从本类找,找不到再向上搜寻。

阿里笔试题(点击查看)

super
  • 修饰属性,表示直接从父类中寻找同名属性。

    • 存在继承关系时,若要访问成员变量,建议加上this,使用this.属性。不加this的话,遵循就近原则,先从本类对象的属性找。若一开始就想使用父类的该属性,使用super.属性

    • super:先从直接父类(爸爸)寻找同名属性,若不存在,向上搜索(爷爷->太爷爷……)

    • 存在继承时,使用this.属性,先从当前类中寻找该属性,若找不到,向父类对象中找。

    • **从直接父类开始向上搜索时,只要找到就停止向上搜索;能不能用该属性取决于该属性在其类内部的访问权限。**比如,在向上找的时候找到了该属性,但是被private修饰,只能在当前父类中使用,这时候也应当停止向上搜索。

  • 修饰方法->构造方法

    • 存在多层继承时,产生子类对象时,先产生父类对象;父类还有父类,继续向上产生。

    • super(父类构造方法的参数)

      若父类中不存在无参构造,则子类构造方法的首行必须显式地调用super(父类有参构造的参数)。

      class Base{
        public Base(String s){
          System.out.print("B");
        }
      }
      public class Derived extends Base{
        public Derived (String s) {
          System.out.print("D");
        }
        public static void main(String[] args){
          new Derived("C");
        }
      }
      //编译错误
      
    • 在一个构造方法中,无法显式地调用this()和super()(两者都必须放在第一行,发生矛盾。)

  • 修饰成员方法

this和super的区别

super不能指代当前父类的对象引用

可以直接打印this,但是不能直接打印super,可以打印super.父类中的属性和方法

继承关系练习题
class X{
	Y y=new Y();
	public X(){
		System.out.print("X");
	}
}
class Y{
	public Y(){
		System.out.print("Y");
	}
}
public class Z extends X{
	Y y=new Y();
	public Z(){
		System.out.print("Z");
	}
	public static void main(String[] args) {
		new Z();
	}
}
//执行结果为:YXYZ

final

  • 修饰属性,表示常量:值定义后无法被修改
  • 修饰类,无法被继承(比如String类)
  • 修饰方法,没有方法复写

类之间的关系

除了继承关系还有组合关系

class School{
    Student student;
    Teacher teacher;
}
//学校里面有学生、老师……

多态

向上转型
  • 向上转型–>父类引用指向子类对象,不一定是直接子类,也可以是孙子类……
  • 向上转型发生在有继承关系的类之间
  • 向上转型的意义是:参数统一化(使用同一个父类引用接受不同的子类实例)
方法重载overload

发生在同一个类中,定义了若干个方法名称相同,参数列表不同,与返回值类型无关

方法重写override

发生在有继承关系的类之间,子类定义了和父类除了权限不同,其他都相同的方法

class Animal{
    public void eat(){
		//1        
	}
}
class Bird extends Animal{
    public void eat(){
        //2
    }
}
class Duck extends Birds{
    public void eat(){
        //3
    }
    public void play(){
        //4
    }
}
Animal a1 = new Animal();
Animal a2 = new Birds();
Animal a3 = new Duck();
a1.eat();//1
a2.eat();//2
a3.eat();//3
//若Duck类中没有重写eat()方法,则从其直接父类向上搜寻,找到第一个重写eat方法的父类,执行该父类重写的eat方法。
//例如,如果Birds和Duck类都没有重写eat(),a3.eat()执行的是1处;如果Birds类重写了eat(),Duck类没有重写eat(),a3.eat()执行的是2处。

当发生重写时,子类方法权限必须>=父类方法权限才可以重写。但是当父类方法权限是private时,即使子类对应的重写方法的权限大于等于private,也不能发生重写。

权限范围大小比较:public > protected > default(包权限) >private

在重写方法前加@Override校验是否符合重写规则


向上转型发生的时机
  • 方法传参

  • 父类引用指向子类对象

  • 方法返回值

    返回值类型为父类,返回一个子类对象的引用

向下转型
Animal animal = new Duck();
animal.play();    //play方法不能调用
//父类引用使用"."操作符调用方法时,能不能调用成功该方法取决于父类中是否包含该方法;调用以后这个方法表现为什么样的状态,取决于new出来的对象是什么类型。

若想调用成功,需借助向下转型

子类名称 子类引用 = (子类名称) 父类引用
Duck duck = (Duck)animal;
duck.play()    //这就可以访问了

要发生向下转型,要转的引用首先必须是向上转型得来的!!!(否则就会报出ClassCastException

instanceof

在向下转型前,先用if(父类引用 instanceof 子类名称)判断是否可以成功转型。

Animal animal1 = new Animal();
Animal animal2 = new Duck();
animal1 instanceof Duck    //返回false
animal2 instanceof Duck    //返回true

抽象类

若需要强制要求子类复写方法,用到抽象类。

注意事项

  • 抽象方法所在的类必须是抽象类;

  • 抽象类可以有多个抽象方法,也可以没有抽象方法;

  • 子类(非抽象类)继承了抽象类,必须复写父类中所有抽象方法(包括父类继承自父类的父类中的抽象方法,但是父类并未实现该方法);

  • 子类(抽象类)继承了抽象类,可以实现父类中的抽象方法,也可以不实现;

  • Java中定义抽象类或者抽象方法使用abstract关键字;

  • 只有方法声明,没有方法体(延迟到子类实现),加abstract关键字

    public abstract void fun();    //抽象方法的声明
    
  • Java中,抽象方法不等于没有方法体的方法

    //本地方法 native
    public final native void notifyAll();    //由JVM实现,JVM是C++写的,这里是调用C++中的方法
    
  • 若一个类声明为抽象类,无法通过该类实例化对象(哪怕该抽象类中一个抽象方法都没有),只能借助子类向上转型变为抽象父类的引用。

    //Person类是一个抽象类,Student类继承自Person类
    Person person = new Person();    //错误
    Person person = new Student();    //正确
    
  • 抽象类虽然没法直接实例化对象,但是也可以存在构造方法。

    abstract class B{
        B(){
            this.print();
        }
        abstract void print();
    }
    public class D extends B{
        //private static int num = 10;
        private int num = 10;
    
        @Override
        void print() {
            System.out.println("num = " + num);
        }
    
        public static void main(String[] args) {
            new D();
        }
    }
    //输出结果为num = 0,若将num设置为静态属性,则输出:num = 10.
    
  • 若一个需求既可以使用抽象类也可以使用接口,优先使用接口,抽象类仍然受单继承局限。

接口

为什么要有接口?

为了让一个方法需要有多种类的对象传参时,参数能兼容

接口的两种场景

  1. 接口表示具备某种行为/能力–>
  2. 接口表示一种规范/标准–>电脑的USB接口和不同的USB设备

编码规范:在接口中,方法不用加public abstract, 全局常量不用加 static final.

注意事项

  • 类实现接口,必须复写接口中所有的抽象方法
  • 接口允许多实现,一个类可能具备多种能力,多个接口之间用逗号分隔。
举报

相关推荐

0 条评论