javase-javabase-210127-01

javase-javabase-210127-01

  • 面向对象 static 构造方法/类构造器
  • 封装 继承 多态 static静态代码块
  • 抽象类 接口 内部类 异常

面向对象

​ Java核心思想-------OOP

  • 物以类聚,分类的思维模式,思考问题首先会解决需要哪些问题,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索
  • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题

对于描述复杂的事务,为了从宏观上把握,从整体合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观,仍然需要面向对象过程的思路去处理。

  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数 据
  • 抽象
  • 三大特向
    1. 封装
    2. 继承
    3. 多态

​ 从认识论角度看,先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象

​ 从代码运行角度看,是先有类后有对象。类是对象的模板

static

public static void main(String[] args){
    
    //和类一起加载的
    public static void a(){}
    
    //类实例化之后才存在
    public void b(){}
}

构造方法 / 类的构造器

​ 在进行创建对象的时候必须要调用的,

  1. 必须和类的名字相同
  2. 必须没有返回类型,也不能写void

封装

​ 程序设计要追求 “ 高内聚,低耦合 ” 。高内聚就是类的内部数据操作细节自己完 成,不允许外部干涉; 低耦合就是仅暴露少量的方法给外部使用

​ 封装(数据的隐藏)(属性私有,get/set):

​ 通常,应禁止直接访问一个对象中数据的世纪表示,而应通过操作接口来访问,这称为信息隐藏。

  • 提高程序的安全性,保护数据
  • 隐藏代码的实现细节
  • 统一接口
  • 系统可维护性增加
public class Test01 {
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(1000);
        System.out.println(person.getAge());//3
    }
}

class Person{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        //可以判断输入有效性
        if(age > 100 || age < 0){
            this.age=3;
        }else{
            this.age = age;
        }
    }
}

继承

​ Java中类只有单继承,没有多继承,extends关键字

​ 子类(派生类),父类(基类)

​ 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等

重写

  1. 继承关系,子类重写父类的方法(方法名一样,方法体不同)

    • 方法名必须一样
    • 参数列表必须相同
    • 修饰符:范围可以扩大 父类是private,子类可以变成public等等
    • 抛出的异常:范围可以被缩小,但不能扩大
  2. 父类的功能,子类不一定需要,或者不一定满足,所以需要重写

public class Test03_Father {
    public void test0301(){
        System.out.println("父类非静态方法");
    }

    public static void test0302(){
        System.out.println("父类静态方法");
    }
}
public class Test03_Son extends Test03_Father{

    @Override   //注解(有功能的注释)
    public void test0301(){
        System.out.println("子类非静态方法");
    }

    public static void test0302(){
        System.out.println("子类静态方法");
    }
}
public class Test03 {
    public static void main(String[] args) {
        /*
               静态方法和非静态的方法区别很大

               静态方法:方法的调用之和左边,定义的数据类型有关
               非静态:  重写
         */

        Test03_Son test0301=new Test03_Son();
        test0301.test0301();//子类非静态方法
        test0301.test0302();//子类静态方法

        //父类的引用指向了子类
        Test03_Father test0302=new Test03_Son();
        test0302.test0301();//子类非静态方法
        test0302.test0302();//父类静态方法
    }
}
this/super
public class Test02_Father {
    private String name="父类变量";

    public Test02_Father() {
        System.out.println("父类无参构造器");
    }

    public Test02_Father(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

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

    public void test02(){
        System.out.println("我是父类的方法");
    }
}
public class Test02_Son extends Test02_Father{
    public String name="子类变量";

    /*
        调用父类构造器,或者调用自身构造器时,
        必须放在方法体的第一行
     */

    public Test02_Son() {
        /*
        这里有隐藏代码,会默认调用父类无参构造器
        super();
         */
        System.out.println("子类无参构造器");

        test02();
        this.test02();
        super.test02();

        test02("子类形参");

    }

    public void test02(){
        System.out.println("我是子类方法");
    }

    public void test02(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.getName());
    }
}
public class Test02 {
    public static void main(String[] args) {
        Test02_Son son=new Test02_Son();
    }
}
  1. super

    • super调用父类的构造方法,必须在构造方法的第一个
    • super必须只能出现在子类的方法或构造方法中
    • super和this不能同时调用构造方法
  2. this

    • 代表的对象不同

      ​ this: 本身调用者这个对象(谁调用它就是谁)

      ​ super: 代表父类对象的应用

    • 前提

      ​ this: 没有继承也可以使用

      ​ super: 只能在继承条件才可以使用

    • 构造方法

      ​ this: 本类的构造

      ​ super: 父类的构造

多态

​ 同一种方法可以根据发送对象的不同而采用多种不同的行为方式

​ 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

​ 存在条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

​ 注意:

  • 多态是方法的多态,属性没有多态
  • 父类和子类有联系
  • 不能实现多态
    1. static方法,属于类,不属于实例
    2. final方法
    3. private方法
public class Test04_F {
    public void speak(){
        System.out.println("父亲说");
    }

    public void run(){
        System.out.println("父亲跑");
    }
}
public class Test04_S extends Test04_F{
    @Override
    public void speak() {
        System.out.println("儿子说");
    }

    public void eat(){
        System.out.println("儿子吃");
    }
}
public class Test04 {
    public static void main(String[] args) {

        //对象能使用那些方法,主要看对象左边的类型,跟右边关系不大

        //子类,能调用的方法都是父类或者自己独有的
        Test04_S test0401=new Test04_S();

        //父类型,可以指向子类,但不能调用子类独有方法(除非强制转换)
        Test04_F test0402=new Test04_S();

        /*
            当父类的引用指向子类,子类重写了父类方法,调用重写方法,会使用子类的重写方法,
            如果子类没有重写父类方法,父类指向子类的引用会使用父类方法,
            如果父类指向子类的引用  调用子类独有的方法(eat)  那么必须强制转换父类指向子类的引用
         */

        test0402.speak();//儿子说
        test0402.run();//父亲跑
        ((Test04_S)test0402).eat();//儿子吃
    }
}
instanceof

​ instanceof 判断一个对象是什么类型

public class Test05_F {
}
public class Test05_S1 extends Test05_F{
}
public class Test05_S2 extends Test05_F{
}
public class Test05 {
    public static void main(String[] args) {
        
        /*
            X instanceof Y      判断 X 是否是 Y 类型的  如果是则为true,否则false
            看看 X Y 是否有父子关系,如果没有,就编译错误
         */
        
        /*
            Object>Test05_F>Test05_S1
            Object>Test05_F>Test05_S2
            Object>String
         */

        Object o=new Test05_S1();
        System.out.println(o instanceof Test05_S1);     //true
        System.out.println(o instanceof Test05_F);      //true
        System.out.println(o instanceof Object);        //true
        System.out.println(o instanceof String);        //false
        System.out.println(o instanceof Test05_S2);     //false
        System.out.println("================================================");


        Test05_F f=new Test05_S1();
        System.out.println(f instanceof Test05_S1);     //true
        System.out.println(f instanceof Test05_F);      //true
        System.out.println(f instanceof Object);        //true
        System.out.println(f instanceof Test05_S2);     //false
//        System.out.println(f instanceof String);        //编译不通过
        System.out.println("================================================");


        Test05_S1 s1=new Test05_S1();
        System.out.println(s1 instanceof Test05_S1);     //true
        System.out.println(s1 instanceof Test05_F);      //true
        System.out.println(s1 instanceof Object);        //true
//        System.out.println(f instanceof String);        //编译不通过
//        System.out.println(f instanceof Test05_S2);     //编译不通过
    }
}
类型转换

​ 从高到低,需要强制转换

  • 父类转子类(向下转型)
public class Test06 {
    public static void main(String[] args) {
        F f=new S();
        //强制转换,可以用父类对子类引用的方法
        ((S)f).eat();
    }
}

class F{
    public void speak(){}
}

class S extends F{
    public void eat(){}
}

​ 从低到高,则不需要强制转换

  • 子类转父类(向上转型),可能丢失一些方法
public class Test0602 {
    public static void main(String[] args) {
        Son son=new Son();
        
        //向上转型,会造成方法的丢失
        Father father=son;
        father.speak();
//        father.eat();     //这个方法用不了
    }
}


class Father{
    public void speak(){}
}

class Son extends Father{
    public void eat(){}
}

static 静态代码块

public class Test0701 {

    /*
        代码块(匿名代码块)
        创建对象的时候就自动创建了
        在构造器之前创建
     */
    {

    }

    /*
        这个是静态代码块(匿名代码块),
        类一加载就执行了,永久只执行一次
        方便初始化东西
     */
    static{

    }
}
public class Test0702 {
    {
        System.out.println("匿名代码块");
    }

    static{
        System.out.println("静态代码块");
    }

    public Test0702(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Test0702 test0702=new Test0702();
        System.out.println("=====================");
        Test0702 test070202=new Test0702();
    }
}

/*
       结果:
        静态代码块
        匿名代码块
        构造方法
        =====================
        匿名代码块
        构造方法
 */
静态导入包
普通:
    
public class Test0703 {
    public static void main(String[] args) {
        System.out.println(Math.random());//产生随机数
        System.out.println(Math.PI);//π的值
    }
}
静态导入包:

import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test0304 {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

抽象类

​ 通过 abstract 修饰符修饰,可以修饰方法,也可以修饰类;若修饰方法,则该方法是抽象方法; 若修饰类,则该类就是抽象类

​ 抽象类中可以没有抽象方法,但有抽象方法的类一定要声明成抽象类

​ 抽象类,不能用 new 关键字来创建对象,它是用来继承的

​ 抽象方法,只有方法声明,没有方法的实现,它是用来让子类实现的

​ 子类继承抽象类,那么必须要实现抽象类没有实现的抽象方法,否则该子类也要声明成抽象类

接口

​ 关键字 interface

​ 接口就是规范,定义的是一组规则

​ 接口的本质是契约(eq:法律人人都要遵守)

​ OO的精髓,是对对象的抽象。

​ 可以通过接口来实现伪多继承(implements)

​ 接口中定义的默认是 public abstract

public interface Test0801 {
    //接口中定义的默认是	public abstract
    public abstract void x();
    void a();
    void b();
}

​ 作用:

  1. 约束
  2. 定义一些方法,让不同的人实现
  3. 默认public static
  4. 可以写静态常量 public static final
  5. 不能被实例化,没有构造方法
  6. 通过implements实现多个接口
  7. 必须重写接口里面的方法

​ 区别:

  • 普通类: 只有具体实现
  • 抽象类: 具体实现和规范(抽象方法)都有
  • 接口: 只有规范(抽象方法),只有约束

内部类

(一个java类中可以有多个class类,但只能有个public class)

​ 内部类就是在一个类的内部再定义一个类,

  • 成员内部类
    1. 可以获得外部类的私有属性,私有方法
  • 静态内部类
    1. 不能获得外部类的私有属性,私有方法;除非把外类也声明为静态的
  • 局部内部类
  • 匿名内部类
//成员内部类

public class Test0901 {

    private int age;
    public void out(){
        System.out.println("外部类方法");
    }

    public class Inner{
        public void in(){
            System.out.println("内部类方法");
            out();
        }
    }
}

//===============================================================
//===============================================================

public class Test0901_T {
    public static void main(String[] args) {
        Test0901 test0901=new Test0901();

        Test0901.Inner inner=test0901.new Inner();
        inner.in();
    }
}
/*
    结果:
        内部类方法
        外部类方法
 */

//静态内部类

public class Test0902 {

    private int age;
    public void out(){
        System.out.println("外部类方法");
    }

    /*
        这个静态内部类先加载了,外部类还没加载呢,所以拿不到外部类的属性
        除非把外部类也搞成static
     */

    public static class Inner{
        public void in(){
            System.out.println("内部类方法");
//            out();//  拿不到了
        }
    }
}
//局部内部类

public class Test0903 {

    //局部内部类
    public void method(){

        class Inner{
            public void in(){

            }
        }
    }
}
//匿名内部类


public class Test0904 {
    public static void main(String[] args) {
        //没有名字初始化类,不用实例保存到变量中
        new A().who();

        //匿名内部类
        B b = new B() {
            @Override
            public void hello() {
                System.out.println("hello");
            }
        };
    }
}

class A{
    public void who(){
        System.out.println("I am A");
    }
}

interface B{
    void hello();
}

异常

​ 三种:

  • 检查性异常

    ​ 代表性检查性异常:常是用户错误或问题引起的异常,这是程序员无法预见 的,eq:打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单忽略

  • 运行时异常

    ​ 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略

  • 错误

    ​ 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。eq:当栈溢出时,一个错误就发生了,它们在编译时也检查不到

​ Java把异常当做对象来处理,并定义了一个基类java.lang.Throwable作为所以异常的超类

​ 这些异常分为两大类, 错误Error 和 异常Exception

处理异常机制
  • 抛出异常
  • 捕获异常

异常处理五个关键字

  1. try
  2. catch
  3. finally
  4. throw 主动抛出异常,一般在方法中使用
  5. throws 在方法中,处理不了这个异常,方法上抛出异常
public class Test01 {
    public static void main(String[] args) {
        int a=1;
        int b=0;

        //抛出多个异常,要从小到大
        try {
            System.out.println(a/b);
        } catch (ArithmeticException e) {       //捕获异常
            System.out.println("被除数不能为0");
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }catch (Throwable e){
            e.printStackTrace();
        }
    }
}
public class Test02 {
    public static void main(String[] args) {
        try {
            new Test02().result(1,0);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }

    //假如在此方法中,处理不了这个异常,throws	方法上抛出异常
    public void result(int a,int b) throws ArithmeticException{
        if(b==0){
            throw new ArithmeticException();//throw 主动抛出异常,一般在方法中使用
        }
    }
}
自定义异常
public class MyException extends Exception{
    private int a;
    public MyException(int a){
        this.a=a;
    }

    @Override
    public String toString() {
        return "MyException{" +  a + '}';
    }
}
public class TestException {
    public static void result(int a) throws MyException {
        System.out.println("传递的参数为"+a);
        if(a>100){
           throw new MyException(a);
        }

        System.out.println("OK");
    }

    public static void main(String[] args) {
        try {
            result(1000);
        } catch (MyException e) {
            System.out.println("MyException is : "+e);
        }
    }
}

方法上抛出异常
public void result(int a,int b) throws ArithmeticException{
if(b==0){
throw new ArithmeticException();//throw 主动抛出异常,一般在方法中使用
}
}
}




#### 	自定义异常

```java
public class MyException extends Exception{
    private int a;
    public MyException(int a){
        this.a=a;
    }

    @Override
    public String toString() {
        return "MyException{" +  a + '}';
    }
}
public class TestException {
    public static void result(int a) throws MyException {
        System.out.println("传递的参数为"+a);
        if(a>100){
           throw new MyException(a);
        }

        System.out.println("OK");
    }

    public static void main(String[] args) {
        try {
            result(1000);
        } catch (MyException e) {
            System.out.println("MyException is : "+e);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值