Java 基础(五)

以下内容来源于B站视频 https://www.bilibili.com/video/BV12J41137hu

面向对象编程

概念

  1. 面向过程与面向对象不可分割
  2. 把一个大项目按照面向对象的思维进行分类,在按照面向过程的思维进行操作
  3. 面向对象编程(Object-oriented Programming, 简称OOP)
  4. 本质:一类的方式组织代码,一对象的组织(封装)数据
  5. 抽象
  6. 三大特征:封装,继承,多态
  7. 从认识角度先有对象,后有类。对象是具体的,类是抽象的,是对对象的抽象(人–>老师)
  8. 从代码运行角度先有对象,后有类,类是对象的模板(通过模板来印钱)

创建与初始化对象

使用new创建

  1. 创建时除了分配内存空间,还会给创建好的对象进行默认初始化以及对类中构造器的调用
  2. 类中的构造器(构造方法),是在进行创建对象的时候必须要调用的,特点:

​ 必须和类的名字相同

​ 必须没有返回类型,也不能写void

//构造器

public class Person {
    //一个类即使什么都不写它也会存在一个方法
}


//他的class文件
package com.oop.demo02;

public class Person {
    //构造器
    public Person() {
    }
}

public class Person {
    //一个类即使什么都不写它也会存在一个方法
    //现实的定义构造器

    String name;
    //实例化初始值
    //1. 使用new关键字,本质是在构造器
    //2. 用来初始化值
    public Person() {  //无参构造
        this.name = "张三";
    }

    //有参构造:一但定义了有参构造,无参就必须显示定义
    //意思是一但有了同名的有参的构造方法,如果想要使用无参的构造方法就必须把无参的构造方法写出来
    public Person (String name) {
        this.name = name;
    }
}


/*
 public static void main(String[] args) {

        //new 实例化了一个对象
        //代码会自动根据有无参数来选择调用那个方法
        Person person = new Person();

        System.out.println(person.name);
    }


    构造器:
       1.和类名相同
       2.没有返回值
    作用:
       1.new 本质在调用构造方法
       2.初始化对象的值
    注意点:
       1. 定义有参构造后,如果想使用无参构造,必须把无参进行显示定义

    this.a(当前类的) =a(参数传进来的值)
 */

创建对象内存分析

  1. String预定义类是不可变的,所以当作常量来处理(String的底层是final修饰的)int可以被改变
  2. 1.8之后字符串常量池和静态变量在堆中,运行时常量池在元空间中,元空间是堆的实现
  3. 方法是被调用后创建的,对象里不包括方法,对象中留了一个isa指针指向代码段,意义是方法体都一样,对象中保留会浪费空间
  4. 堆存储new的对象和数组元素,站存储系统调用变量(例如基本变量和引用变量)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RAtvjBn2-1621387921543)(C:\Users\x9257\Desktop\Java\4.PNG)]

public class Pet {
    public String name;
    public int  age;

    public void shout() {

        System.out.println("叫了一声");
    }
}


/*
public static void main(String[] args) {
        Pet dog = new Pet();
        //dog相当于一个容器,存放Pet()对象的地址,就是一段地址,通过这个地址去找到堆中对应的对象,相当于通过一个人的名字去找一个人
        dog.name = "旺财";
        dog.age = 3;
        dog.shout();

        System.out.println(dog.name);
        System.out.println(dog.age);
    }
 */

小结

  1. 类与对象

​ 类是一个模板:抽象,对象是一个具体的实例

  1. 方法

​ 定义,调用

  1. 对应的引用

​ 引用类型:基本类型(8)

​ 对象是通过引用来操作的

  1. 属性:字段Field 成员变量

​ 默认初始化:

​ 数字: 0 0.0

​ char:u0000

​ boolean:false

​ 引用:null

​ 修饰符 属性类型 属性名 = 属性值

  1. 对象的创建和使用

    - 必须使用new 关键字创建对象     有构造器    例: Person  zhangsan = new  Person();
    - 对象的属性    zhangsan.name
    - 对象的方法    zhagnsan.sleep();
    

​ 静态的属性 属性

​ 动态的行为 方法

封装

  1. 程序设计要求"高内聚,低耦合"

​ 高内聚:类的内部数据操作细节自己完成,不允许外部干涉

​ 低耦合:仅暴露少量的方法给外部使用

  1. 封装(数据的隐蔽) 禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问
  2. 属性私有 get/set
package com.oop.Demo04;

public class Student {
    //属性私有
    private String name;
    private String id;
    private String sex;
    private int age;

    //提供一些操作属性的方法
    // 提供一些public 的get,set方法
    //get 获得这个数据
    public String getName(){
        return this.name;
    }

    // set 给这个数据设置值
    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>120 || age<0) {   //使用get,set方法来判断输入是否合法
            this.age = 3;
        }else {
            this.age = age;
        }

    }

    //alt + insert生成get ,set方法
}



/*
1. 提高程序安全性,保护数据
2. 隐藏代码实现细节
3. 统一接口
4. 系统可维护增加了
 
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();


        s1.setName("张三");

        System.out.println(s1.getName());


        s1.setAge(121);
        System.out.println(s1.getAge());

    }




}
 */

继承

  1. 本质是对某一批类的抽象,从而实现对现实世界更好的建模
  2. extends 扩展 ,子类是父类的继承
  3. JAVA中只有单继承,没有多继承(一个儿子只能有一个父亲,一个父亲可以有多个儿子)
  4. 继承是类和类之间的一种关系。类和类之间还有依赖,组合,聚合
  5. 继承关系的两个类一个为子类(派生类),一个为父类(基类)
  6. 子类和父类之间有“is a"关系
  7. ctrl + H
  8. Object是所有类的父类,他们都直接或间接 继承Object
public class Person {
    //public 子类可以继承 父类
    //protected  受保护的
    //private 子类不可以继承
    //default   默认的
    //在Java中,所有类都默认直接或者间接继承Object

    private  int money = 10000;

    public void say() {
        System.out.println("说了一句话");
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}




public class Student extends Person {

}



public class Application {
    public static void main(String[] args) {

        Student student = new Student();

        student.say();

        System.out.println(student.getMoney());

    }

}
  1. 一个构造函数中不能同时出现this和super两种方法,因为this函数中也有super,这会导致初始化两次,数据不安全
  2. 若父类只含有参构造器,没有写无参构造的话,在子类无参构造中要想不报错,就要显示调用父类含参方法

小结

super注意点:

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

Vs(Visual Studio ) this:

​ 代表对象不同

​ this:本身调用者这个对象

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

​ 前提

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

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

​ 构造方法

​ this(); 本类的 构造

​ super(); 父类的构造

多态

  1. 父类的引用指向子类 Person(父类) s2 = new Student();(子类)类似于:我是一个学生,我也是一个人
  2. 编译看左,运行看右
  3. 高到低要强制转换
  4. 父类引用子类对象也称为向上造型
  5. 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
  6. 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
  7. 多态存在的条件:
    ·有继承关系
    ·子类重写父类方法
    ·父类引用指向子类对象
  8. 多态的概念,可以理解为:方法的调用除了本类对象可以调用自己以外,在方法重写里还可以通过父类对象的引用来调用自己

注意事项:

    - 多态是方法的多态,属性没有多态(属性是静态的,方法是动态的)
    - 父类和子类,有联系,类型转换异常 ClassCastException
    - 存在条件:继承关系,方法需要重写(那个类有运行那个,如果都有运行子类的),父类的引用指向子类    Father f1 = new son();

​ 哪些方法无法重写

                  1. static 方法,属于类,他不属于实例
                     2. final 常量
                     3. private 方法
package com.oop;


import com.oop.Demo06.Person;
import com.oop.Demo06.Student;


public class Application {

    public static void main(String[] args) {

      //一个对象的实际类型是确定的   new 什么就是什么
        //new Student();
        //new Person();

        //可以执行的引用类型就不确定了:父类的引用指向子类

        //student能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //父类型可以指向子类,但是不可以调用子类独有的方法
        Person  s2 = new Student();
        Object  s3 = new Student();
        //对象能执行那些方法,主要看对象左边的类型,和右边关系不大   Person  s2 = new Student();  主要看Person有没有
        s1.run();
        s2.run();


        s2.eat();


    }
}



public class Student extends Person{

    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat(){
        System.out.println("eat");
    }


}


public class Person {
    public void run () {
        System.out.println("father");
    }
}

instanceof

  1. instanceof实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的子类
  2. System.out.println(x instanceof f); x与y之间是否存在直接继承
  3. 主要看new 后面的
 public static void main(String[] args) {

        Object object = new Student();

        System.out.println(object instanceof Student);
        System.out.println(object instanceof Person);
        System.out.println(object instanceof Object);
        System.out.println(object instanceof Teacher);
        System.out.println(object instanceof String);

        System.out.println("=============");

        Person person = new Student();

        System.out.println(person instanceof Student);
        System.out.println(person instanceof Person);
        System.out.println(person instanceof Object);
        System.out.println(person instanceof Teacher);
       // System.out.println(person instanceof String);//编译出错

        System.out.println("=============");

        Student student = new Student();

        System.out.println(student instanceof Student);
        System.out.println(student instanceof Person);
        System.out.println(student instanceof Object);
        //System.out.println(student instanceof Teacher);//编译出错
        //System.out.println(student instanceof String);//编译出错
    }

小结

  1. 父类引用指向子类对象
  2. 把子类转换为父类,向上转型 会对丢失方法
  3. 把父类转换为子类 向下转型 强制转换
  4. 方便方法的调用,减少重复的代码
public class Person {

    public void run(){
        System.out.println("run");
    }

}


public class Student extends Person{


    public void go(){
        System.out.println("go");
    }


}


public class Teacher extends Person{
}


public class Application {


    public static void main(String[] args) {
        //类型之间的转换: 父   子

        //高      低
        Person obj = new Student();

        //student将这个对象转换为Student类型,我们就可以使用Student类型独有的方法了

        Student student = (Student)obj;
        student.go();//就是父类用不了子类独有的方法,所以把自己伪装成子类


        //子类转换为父类,可能丢失一些方法
        Student student1 = new Student();
        student1.go();
        Person person = student1;
        //person.go();
    }

}

static

  1. 加了static就是从属于这个类,其他人用不了 就行了 只有本类能用
  2. 静态的一直存在,非静态的需要打开了才能用
  3. 掌握一个原则:static属于类,非static属于对象
  4. static这里说的意思是,原本Java文件编译成class文件,如果有static关键字,就会一起加载进去初始化,没有static的话,你就需要new了才会加载,比较jvm比较懒,不会全部加载
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;

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



public class Person {
    //2.赋初始值
    {
        //代码块(匿名代码块)
        System.out.println("匿名代码块");
    }

    //1.只执行一次
    static {
        //静态代码块
        System.out.println("静态代码块");
    }
    //3
    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person1 = new Person();

        System.out.println("===============");

        Person person2 = new Person();


    }
}



public class Student {

    private static int age;   //静态变量
    private double score;     //非静态变量

    public void run () {

    }

    public static void go() {

    }

    public static void main(String[] args) {

        //属性
        Student s1 = new Student();

        System.out.println(s1.age); //对象调用  静态非静态都可
        System.out.println(s1.score);
        System.out.println(Student.age);// 类名访问   类名只能访问静态变量
        //System.out.println(Student.score);


        //方法
        new Student().run();//非静态方法访问
        Student.go(); //静态方法访问
        go();
    }
}

抽象类

  1. 用abstract修饰符来修饰方法或类,成为抽象方法或抽象类
  2. 抽象类中可以没有抽象方法,但有抽象方法的类一定要声明为抽象类
  3. 抽象类不能用new关键字来创建对象,它是用来让子类继承的
  4. 抽象方法只有方法声明,没有方法实现,它是用来让子类实现的
  5. 子类继承抽象类,那么就必须实现抽象类没有实现的抽象方法,否则盖子类也要声明为抽象类
  6. 抽象类和抽象方法其实就是一种标准,保证后续的代码都按照这个标准进行实现
  7. 如果抽象类中有普通方法想调用也必须通过子类来进行。
  8. 抽象类就相当于房子的图纸,设计好了让子类去把房子做出来
  9. 抽象类就是来实现封装,多态的增强代码的可扩展性
  10. 为了 提高开发效率
  11. 抽象类特点
  • 不能new抽象类,只能靠子类去实现它:约束
  • 有构造器

接口

  1. 只有规范,自己无法写方法,是专业的约束! 使实现和约束分离
  2. 接就是规范,定义的是一组规则,例如如果你是汽车,就必须能跑
  3. 接口的本质是契约,就像我们的法律一样
  4. OO的精髓,是对对象的抽象,最能体现这一点的就是接口设计模式所研究的实际上就是如何合理地去抽象

作用:

  • 约束
  • 定义一些方法,让不同的人实现
  • 方法:public abstract
  • 常量public static final
  • 接口不能被实例化,接口中没有构造方法
  • implements可以实现多个接口
  • 必须要重写接口中的方法
//interface  定义关键字    接口都需要有实现类
public interface UserService {
    //常量  public static final
    int age = 99;

    //接口中的所有定义其实都是抽象的public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}


public class UserServiceImpl implements UserService,TimeService{

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {

    }
}



public interface TimeService {
    void timer();
}

内部类

  1. 只要内部类的访问权限不比外部类高就可以了
public class Outer {
    private int id;

    public void out() {
        System.out.println("这是外部类的方法");
    }

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

        //获得外部类的私有属性
        public void getID() {
            System.out.println(id);
        }

        //获得外部类的方法
        public void getMethod() {
            Outer.this.out();
        }


    }
}



public class Application {


    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
        inner.getMethod();
    }

}

异常机制

简介

  1. 程序运行中出现不期而至的各种情况
  2. 发生在程序运行期间,他影响了正常的程序执行流程
  3. 检查性异常:代表用户错误和问题引起的异常,是程序员无法预见的,在编译时不能被忽略 测试
  4. 运行时异常:他是可能被程序员避免的异常,在编译时会被忽略
  5. 错误ERROR:错误不是异常,而是程序员控制的问题。错误在代码中通常被忽略,他们在编译时也检查不到 异常处理框架

Exception

  1. 在Exception分支中有一个重要的子类RuntimeException(运行时异常)

      - ArraylndexOutOfBoundsException(数组下标越界)
         
      - NullPointerException(空指针异常)
         
      - ArithmeticException(算术异常)
         
      - MissingResourceException(丢失资源)
         
      - ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
      - 这些异常一般是由程序逻辑错误引起的
    

Error和Exception区别

Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止程序

Exception 通常情况下是可以被程序处理的,并且在程序中应该尽可能去处理这些异常

public class Test2 {
    public static void main(String[] args) {

    }
    //throw 创建异常     throws 抛出异常

    //假设这个方法中处理不了这个异常,方法上抛出异常
    public void test(int a,int b) throws ArithmeticException {
        if(b==0) {
            throw new ArithmeticException();//主动抛出异常,一般在方法中使用
        }
    }
}


/*
int a = 1;
        int b = 0;

        //Ctrl + Alt + T  自动生成异常代码

        try {
            System.out.println(a/b);
        } catch (Exception e) {
            System.exit(1); //结束程序
            e.printStackTrace();//打印错误栈信息
        } finally {
        }
 */







public class Test {
    public static void main(String[] args) {

        int a = 1;
        int b = 0;
        //捕获异常要从小到大捕获

        try {//try监控区域
            System.out.println(a/b);
        }catch (Error e) { //catch(想要捕获的异常类型)捕获异常
            System.out.println("程序出现异常");
        }catch (Exception e) {
            System.out.println("Exception");
        } catch(Throwable e) {
            System.out.println("Throwable");
        } finally {//处理善后工作
            System.out.println("程序结束");
        }
    }
}

自定义

  1. 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch处理

  2. 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常

  3. 对于不确定的代码,也可以加上try-catch、处理潜在的穿常

  4. 尽量去处理异常,切忌只是简单地调用printStack Trace()去打印输出

  5. 具体如何处理异常,要根据不同的业务需求和异常类型去决定

  6. 尽量添加finally语句块去释放占用的资源

public class Test {
    //可能会存在异常的方法
    static void test(int a) throws  MyException {
        System.out.println("传递的参数为:" + a);

        if(a>10) {
            throw new MyException(a);
        }

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


    public static void main(String[] args) {
        try {
            test(12);
        } catch (MyException e) {
            //增加一些处理异常的代码块
            System.out.println("MyException ==> " + e);
        }
    }
}






public class MyException extends Exception{
    private int detail;

    public MyException(int a) {
        this.detail = a;
    }

    //toString 打印异常信息

    @Override
    public String toString() {
        return "MyException{" +
                "detail=" + detail +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值