Java面向对象

Java面向对象

面向对象(Object-Oriented Programming)编程本质:

以类的方式组织代码,以对象的方式封装数据

三大特性

封装

继承

多态

01、类与对象的创建

package com.oop.Demo01;

/**
 * Created by Q on 2022/1/15.
 */
public class Demo01 {
    public static void main(String[] args) {
//        Student.say();   静态方法可直接调用

//        非静态方法要先实例化
        Student student = new Student();
        student.say();
    }
    //静态方法和类一起加载
    public static void a(){
//        b();
    }
    //非静态方法是在类实例化后才存在的,故不能有静态方法调用
    public void b(){
    }
}

值传递

package com.oop.Demo01;

/**
 * Created by Q on 2022/1/16.
 */
public class Demo02 {
    public static void main(String[] args) {
        //值传递
        int a = 10;
        System.out.println(a);  //10
        Demo02 demo02 = new Demo02();
        demo02.change(a);
        System.out.println(a);  //10
    }
    public static void change(int a){
        a = 1;
    }
}

02、构造器

又叫构造方法

package com.oop.Demo02;

/**
 * Created by Q on 2022/1/18.
 */
public class Person {
    //一个类即使什么都不写,也存在一个方法 public Person() {} java--->class文件
    //显示的定义构造器
    String name;  //null
    int age;
    //作用:实例化初始值
    //使用new关键字必须有构造器,因为本质是在调用构造器
    public Person() {
    }

    //有参构造
    //使用有参构造,必须显式定义无参构造否则报错
    // Person(String)in Person cannot be applied to()
    //快捷键 alt+insert
    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
/**
	 public static void main(String[] args) {
 		Person person = new Person("Q",10);
 		System.out.println(person.name);
 		System.out.println(person.age);
 	}
 */
}

构造器:

  • 和类名相同

  • 没有返回值

  • 作用:

    1、实例化初始值

    2、使用new关键字本质是在调用构造器

  • 注意点:

​ 1、使用有参构造,必须显式定义无参构造,否则报错

​ 2、快捷键 alt+insert

扩展 创建对象内存分析

待完善

待完善

03、封装

将类中属性(+少方法)私有化

package com.oop.Demo03;

/**
 * Created by Q on 2022/1/20.
 */
public class Student {
    //封装
    //属性私有
    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 > 0 && age < 120){
            this.age = age;
        }else {
            this.age = -1;
        }
    }
}

04、继承

对象抽象出类 对象抽象----->类

子类抽象出父类 子类抽象------>父类 子类继承父类

4-1 Object类

4-2 super this

package com.oop.Demo04;

/**
 * Created by Q on 2022/1/20.
 */
//父类
//java中,所有类直接或者间接继承Object类
public class Person {
    //私有属性不可继承
    private int money = 1_0000_0000;
    protected String name = "Person_Q";

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

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

    public void say(){
        System.out.println("说话了");
    }
    //get set
    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
package com.oop.Demo04;

/**
 * Created by Q on 2022/1/20.
 */
//子类(继承类)  ctrl+H:查看类继承结构
//继承父类所有方法
public class Student extends Person {
    private String name = "Student_Q";

    public Student() {
        //隐藏代码:默认调用父类无参构造
        super();  //只能放在子类构造器第一行
        System.out.println("子类无参构造");
    }
    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        print();  //Student
        this.print();  //Student
        super.print();  //Person
    }

    public void test(String name){
        System.out.println(name);  //test_Q
        System.out.println(this.name);  //Student_Q
        System.out.println(super.name);  //Person_Q
    }
}

/**
 public static void main(String[] args) {
 com.oop.Demo04.Student s1 = new com.oop.Demo04.Student();
 s1.say();
 s1.test("test_Q");
 }
 */

super注意点:

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

VS this

​ 代表的对象不同:
​ this:本身调用者这个对象
​ super:代表父类对象的引用
​ 前提不同:
​ this:没有继承也可以使用
​ super:只能在继承的条件下才可以使用
​ 构造方法:
​ this:本类的构造
​ super:父类的构造

4-3 方法重写

重写是方法的重写和属性无关

//不是重写
public class A {
    public static void test(){
        System.out.println("A==>test");
    }
}

public class B extends A{
    public static void test() {
        System.out.println("B==>test");
    }
}

public class Application {
    public static void main(String[] args) {
    	//父类的引用指向子类
        A a = new B();
        a.test();  //A==>test
        
        B b = new B();
        b.test();  //B==>test
    }
}
//重写
public class A {
    public void test(){
        System.out.println("A==>test");
    }
}

public class B extends A{
    //注解
    @Override  //重写
    public void test() {
        System.out.println("B==>test");
    }
}


public class Application {
    public static void main(String[] args) {
        A a = new B();
        B b = new B();
        a.test();  //B==>test
        b.test();  //B==>test
    }
}

重写小结:要是非静态方法

  1. 需要有继承关系,子类重写父类的方法!

  2. 方法名必须相同,参数列表必须相同

  3. 修饰符:

    范围可以扩大:public > Protected > Default > private

  4. 抛出的异常:

    范围可以被缩小,但不能扩大;

    ClassNotFountException —> Exception(大)

  5. 重写,子类的方法和父类必须要一致,方法体不同!

为什么需要重写?

父类的功能,子类不一定需要,或者不一定满足!

05、多态

多态存在的必要条件:

  • 继承
  • 重写 (子类重写父类方法,方法名必须相同)
  • 父类引用指向子类对象:Parent p = new Child();

06、instanceof关键字

X instanceof Y X是否是Y的实例

package com.oop;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;
public class Application {
    public static void main(String[] args) {
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();
        //System.out.println(X instanceof Y);//能不能编译通过,就取决于X和Y之间是否存在父子关系;
        //结果是true或者false ,X所指向的实例类型是Y的子类型,或者 X和 Y是有关系的
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false,String是 Object lang包下面的,更没关系了
        System.out.println("===================================");
        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(person instanceof String);//编译报错!string和 person同级,它是两条线
        System.out.println("===================================");
        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);//false,编译报错!
                // instanceof是一个比较转换的过程,比较肯定是两边有关系的才会返回true或者false
        //System.out.println(student instanceof String);//false,编译报错! 两者没关系会直接报错
    } 
}

多态总结:

    1. 父类引用指向子类的对象(子类引用指向父类的对象肯定是不行的)
    2. 把子类转换为父类,也就是向上转型:不用强制转换;
    3. 把子类转换为父类,也就是向下转型:需要强制转换;(可能会丢失一些方法)
    4. 方便方法的调用,减少重复的代码!简洁

07 、static关键字小结

静态属性

//static
public class Student {
    private static int age;//静态的变量  多线程!
    private double score;//非静态的变量
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(Student.age);//类变量跟类中的所有实例共享
        //System.out.println(Student.score);这是不行的
        System.out.println(s1.age);
        System.out.println(s1.score);
    }
}

静态方法

//static
public class Student {
    private static int age;//静态的变量  多线程!
    private double score;//非静态的变量
    public void run(){//非静态方法可以调用静态方法里的所有东西
        go();
    }
    public static void go(){//静态方法可以调用静态方法里的所有东西
    }
    public static void main(String[] args) {
        new Student().run();//对象.方法
        Student.go();
        go();
    }
}

静态代码块

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();
    }
    /*
        结果:
            静态代码块
            匿名代码块
            构造方法
            =================
            匿名代码块
            构造方法
     */
}

package的一些新特性

//静态导入包~
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);
    }
    /*
    final 通过final修饰的类不能被继承,就没有子类
     */
}

08、抽象类(abstract)

  • 抽象类特点

    1. 抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中
    2. 抽象类不可以直接创建对象,原因:调用抽象方法没有意义
    3. 只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象,否则该子类还是一个抽象类
  • abstract不能和哪些关键字共存?

    1. private 被私有的成员只能在本类中调用,而abstract强制重写抽象方法,二者冲突
    2. final final表示最终的,被修饰的类和方法不能被继承和重写,与abstract强制重写抽象方法冲突
    3. static 无意义
//abstract修饰的类为抽象类,java的类是单继承(接口可以多继承)
public abstract class Action {
    //抽象方法,可以实现约束作用,让继承的子类来实现方法。
    //abstract,抽象方法,只有方法名字,没有方法的实现!
    public abstract void doSomething();
    //抽象类不能new出对象,只能用子类去实现。
    //抽象类里可以写普通方法
    //抽象方法必须在抽象类中
    //抽象的抽象:约束
    //存在的意义,提高开发效率。
}

public class A extends Action{
    @Override
    public void doSomething() {
    }
}

09、接口

  • 接口的成员特点

    • 成员变量:只能是常量,并且是静态的,默认有public static final修饰
    • 成员方法:只能是抽象方法,默认有public abstract修饰
    • 构造方法:接口没有构造方法
    package com.oop.Demo06;
    
    /**
     * Created by Q on 2022/1/23.
     */
    //接口
    public interface UserService {
        void add(String name);
        void delete(String name);
        void update(String name);
        void query(String name);
    }
    //接口实现类
    public class UserServiceImpl implements UserService {
        @Override
        public void add(String name) {
    
        }
    
        @Override
        public void delete(String name) {
    
        }
    
        @Override
        public void update(String name) {
    
        }
    
        @Override
        public void query(String name) {
    
        }
    }
    

10、内部类

  1. 成员内部类
  2. 静态内部类(static 修饰)
  3. 局部内部类
  4. 匿名内部类
package com.oop.Demo07;

/**
 * Created by Q on 2022/1/23.
 */
public class Outer {
    private String name;
    public void out(){
        System.out.println("外部类");
    }
    public class Inner{
        public void in(){
            System.out.println("内部类");
        }
        //作用:获得内部类的私有属性
        public void getName(){
            System.out.println(name);
        }
    }
}

/*
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.out();  //外部类
        Outer.Inner in = outer.new Inner();
        in.in();  //内部类
        in.getName();  //Q
    }
 */

小疑惑 UserService userservice = new UserService()

//一个Java类中可以有多个class类,但是只能有一个public class
public class Outer {
    public static void main(String[] args) {
        new Apple().eat();
        //匿名内部类
        UserService userservice = new UserService(){
            @Override
            public void Hello() {
            }
        };
    }
}
//局部内部类
class Apple{
    public void eat(){
        System.out.println("1");
    }
}
interface UserService{
    void Hello();
}

11、类、接口、抽象类小结

类与类,类与接口,接口与接口的关系

  • 类与类:继承关系,只能单继承,可以多层继承
  • 类与接口:实现关系,可以单实现,也可以多实现。并且可以在继承一个类的同时实现多个接口
  • 接口与接口:继承关系,可以单继承,也可以多继承

抽象类和接口的区别

  • 成员区别

    抽象类:

    成员变量:可以是变量,也可以是常量

    成员方法:可以是抽象类,也可以非抽象类

    构造方法:有

    接口:

    成员变量:只能是常量

    成员方法:只能是抽象类

    构造方法:无

  • 关系区别

    抽象方法:

    类与类:继承,单继承
    类与接口:实现,单实现,多实现
    接口与接口:继承,单继承,多继承

  • 设计理念区别

    抽象类:体现的是“is a ”的关系,抽象类中定义的是该继承体系的共性功能

    接口:体现的是“like a ”的关系,接口中定义的是该继承体系的个性功能(扩展功能)

12、异常

Error和Exception

Exception

12-1 异常层次结构图示

(引用菜鸟教程)

exception层次

12-2 关键字

  1. try
  2. catch
  3. finally
  4. throw
  5. throws
package com.exception;

/**
 * Created by Q on 2022/1/23.
 */
public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        //Ctrl+Alt+t  快捷键:捕获结构代码
        try{//监控区
            System.out.println(a/b);   //Exception in thread "main" java.lang.ArithmeticException: / by zero
        }catch (ArithmeticException e){  //捕获
            System.out.println(e);
        }catch (Error error){
            System.out.println("Error");
        }catch (Exception exception){
            System.out.println("Exception");
        }catch (Throwable throwable){
            System.out.println("Throwable");
        }finally {  //善后处理   finally可以不用,用于处理IO流等关闭资源
            System.out.println("其他异常");
        }
    }
}
/*
输出结果:
java.lang.ArithmeticException: / by zero
其他异常
 */

12-3 自定义异常

package com.exception.Demo02;

/**
 * Created by Q on 2022/1/23.
 */
public class MyException extends Exception{
    private int detail;
    //参数大于10抛异常
    public MyException(int detail) {
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "MyException{" + "detail='" + detail + '\'' + '}';
    }
}
//测试
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(14);
        } catch (MyException e) {
            System.out.println(e);

        }
    }
}
/*
参数:14
MyException{detail='14'}
 */

后记(有感)

从2022年1月1号准备开始学习,至今23号,经过23天(实际最多只需要一周就可以搞定,打脸自己flag)断断续续的学习,课程是B站狂神说Java的JavaSE课程,记录了这么一份笔记,其中有的是借鉴偷懒直接c(但是少数),希望可以用来以后回顾。能感觉出来这是一份速学课程,相对而言少了很多知识点,适合急找工作速成。后续再找点资料补充完善java体系。

补充待续

posted @ 2022-01-23 22:31  Code7Rain  阅读(29)  评论(0)    收藏  举报