java基础课堂随记9

面相对象编程

  1. 初识面向对象
  2. 方法回顾和加深
  3. 对象的创建分析
  4. 面向对象三大特性
  5. 抽象类和接口
  6. 内部类及OOP实战

https://img.rruu.net/image/603ee38c2ef99

回顾方法定义:

package OOP;

//Demo1 就是一个类
public class Demo1 {
    public static void main(String[] args) {

    }

    /*
    修饰符  返回值类型  方法名(...){
    //方法体
    return 返回值;
    }
     */
    public String sayHello(){
        return "Hello World!"
    }

    public void hello(){
        return;
    }

    public int max(int a,int b){
        return a>b ? a : b//三元运算符
    }
}

回顾方法的调用:

package OOP;

public class Demo2 {

    public static void main(String[] args) {
//实例化这个类 new
        //对象类型  对象名 =  对象值
        Student student = new Student();

        student.say();


    }
    //静态方法 static

    //和类一起加载的
    public static void a(){

    }
    //类实例化之后才存在,所以从a里面直接调用b的时候不可以,因为还不存在
    public void b(){

    }
    //非静态方法
}

package OOP.demo1;

public class Demo3 {
    public static void main(String[] args) {
        //实际参数与形式参数相对应
        int add = Demo3.add(1, 2);
        System.out.println(add);
    }
    public static int add(int a, int b){
        return a+b;
    }
}

//值传递
public class Demo4 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);

        Demo4.change(a);
        System.out.println(a);//输出为1

    }
    public static void change(int a){
        a = 10;
    }
}
package OOP.demo1;

//引用传递:对象,本质还是值传递
public class Demo5 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);//null

        Demo5.change(person);

        System.out.println(person.name);//hjh
    }
    public static void change(Person person){
        //person是一个对象,指向的--->Person person = new Person();这是一个具体的人,可以改变属性

        person.name = "hjh";
    }
}

//定义一个Person类,有一个属性:name
class Person{
    String name;//null
}

类与对象的关系:

类是一种抽象的数据类型,它是对某一事物整体描述/定义,但是并不能代表某一个具体的事物:如动物,植物,手机,电脑....

Person类,Pet类,Car类,这些类都是用来描述,定义某一类具体事物应该具有的特点和行为

对象是抽象概念的具体实例

张三是一个人

能体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念

package OOP.demo2;

//学生类
public class Student {

    //非静态方法
    public void say(){
        System.out.println("学生说话了");
    }

    //属性:  字段
    String name;//null
    int age;//0

    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}

package OOP.demo2;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {

        //类是抽象的,需要实例化
        //类实例化后会返回一个自己的对象
        //student对象就是Student类的一个具体实例
        Student student = new Student();
        student.name = "Ezeral";
        student.age = 3;
        System.out.println(student.name);
        System.out.println(student.age);
    }
}

创建与初始化对象

https://img.rruu.net/image/603f233c9cc4e

一个类即使什么都不写,也会存在一个方法

alt+insert,可以直接生成构造器

package OOP.demo2;

//java文件---->class 文件
public class Person {
    //一个类即使什么都不写,也会存在一个方法
    //显示的定义构造器

    String name;

    //实例化初始值
    //使用new关键字,本质是在调用构造器
    public Person(){
        this.name = "hjh";
    }

    //有参构造:一旦定义了有参构造,无参就必须显示定义
    public Person(String name){

        this.name = name;
    }
}

构造器:

  1. 和类名相同
  2. 没有返回值

作用:

  1. new 本质在调用构造方法
  2. 初始化对象的值

注意点:

  1. 定义有参构造之后,如果想使用无参构造,显示的定义一个无参构造

创建对象内存分析:https://img.rruu.net/image/603f2e6ae3fdd

简单小结类与对象:

  1. 类与对象:类是一个模板:抽象,对象是一个具体的实例
  2. 方法:定义,调用!
  3. 对应的引用:

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

对象是通过引用来操作的:栈----->堆

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

默认初始化:

​ 数字:0 0.0

​ char: u0000

​ boolean : false

​ 引用:null

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

  1. 对象的创建和使用

    ​ 必须使用new关键字创造对象,构造器

    ​ Person hjh = new Person();

    对象的属性 hjh.name

    对象的方法 hjh.eat()

  2. 类:

    静态的属性 属性

    动态的行为 方法

  3. 三大特征:封装、继承、多态

封装

https://img.rruu.net/image/603f35bdedbfd

alt+insert可以自动生成getName和setName方法

封装的作用:

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口
  4. 系统可维护增加了
package OOP.demo4;

//类 private:私有
public class Student {

    //名字
    private String name;
    //学号
    private int id;
    //性别
    private char sex;
    //年龄
    private int age;
    //学习()
    //睡觉()

    //提供一些可以操作这个属性的方法
    //提供一些public的get,set方法

    //get   获得这个数据
    public String getName(){
        return this.name;
    }

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

    public int getId() {
        return id;
    }

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

    public char getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>120||age<0){//不合法
            this.age = 3;
        }else {
            this.age = age;
        }

    }
}

package OOP;

import OOP.demo4.Student;

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("hjh");
        String name = s1.getName();
        System.out.println(s1.getName());

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

    }
}

继承

https://img.rruu.net/image/6040369481b1d

注意在new Student 的时候,可以选择是哪个package里面的Student,我一开始选择到04里面的student,结果打不出来。这个在new的时候就会提示你

在继承里面,如果写的是private则无法继承,public可以继承

优先级顺序:

public

protected

default(默认状态)

private,一般属性会设置这种状态

在java中,所有的类,都默认直接或间接继承Object类

package OOP.demo5;

//父类
public class Person {

    private int money = 10_0000_0000;

    public int getMoney() {
        return money;
    }

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

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

然后创建Student和Teacher包,继承Person,可以直接调用student.Person中的方法

package OOP;

import OOP.demo5.Student;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();

        //ctrl+H可以调出继承树

    }
}

super注意点:

  1. super调用父类的构造方法,必须在构造方法的第一个
  2. super 必须只能出现在子类的方法或者构造方法中!
  3. super和this不能同时调用构造方法,因为它们都得放在第一行
package OOP.demo5;

//父类
public class Person {
    protected String name = "hjh";

}

package OOP.demo5;

//学生  is  人 :派生类,子类
public class Student extends Person{
    private String name = "Frank";
    public void test(String name){
        System.out.println(name);//胡
        System.out.println(this.name);//Frank
        System.out.println(super.name);//hjh
    }
}

package OOP;

import OOP.demo5.Student;

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

        Student student = new Student();
        student.test("胡");
    }
}

这几个代码可以看出调用顺序的不同

VS this:

​ 代表的对象不同:

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

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

​ 前提

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

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

​ 构造方法

​ this();本类的构造

​ super(); 父类的构造

package OOP.demo5;

//学生  is  人 :派生类,子类
public class Student extends Person{

    public Student() {
        //隐藏代码,调用了父类的无参构造
        //相当于这里有个super();,而且调用父类的构造器,必须要在子类的第一行
        System.out.println("子类的无参执行了");
    }


}
package OOP.demo5;

//父类
public class Person {
    protected String name = "hjh";

    public Person() {
        System.out.println("Person无参执行了");
    }
}
package OOP;

import OOP.demo5.Student;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();

//        Student student = new Student();
//        student.test("胡");
    }
}

方法重写

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

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符:范围可以扩大,但不可以缩小:public>protected>default>private
  4. 抛出的异常:范围可以被缩小,但不能扩大。ClassNotFoundExpection---->Expection(大)

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

为什么需要重写:

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

  2. 快捷键:Alt+Insert---->override;

    package OOP;
    
    import OOP.demo5.A;
    import OOP.demo5.B;
    import OOP.demo5.Student;
    
    public class Application {
        public static void main(String[] args) {
    //静态方法和非静态方法区别很大!
            //静态方法:方法的调用,只和左边定义的数据类型有关
            //非静态:重写
    
            A a = new A();
            a.test();//A
    
            //父类的引用指向了子类
            B b = new A();//子类重写了父类的方法
            b.test();//B
        }
    }
    
package OOP.demo5;
//继承
public class A extends B{
    @Override//注解:有功能的注释。Override就是重写的意思
    public void test() {
        System.out.println("A===>test()");
    }
}
package OOP.demo5;

//重写都是方法的重写,和属性无关
public class B {
    public void test(){
        System.out.println("B===>test()");
    }
}

多态

https://img.rruu.net/image/6040812910592

package OOP.demo6;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
package OOP.demo6;

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

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

import OOP.demo6.Person;
import OOP.demo6.Student;

public class Application {
    public static void main(String[] args) {
        //一个对象的实际类型是确定的
//        Student student = new Student();
//        Person person = new Person();
        //可以指向的引用类型就不确定了:父类的引用指向子类

        //Student能调用的方法都是自己的,或者继承父类的
        Student s1 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大 !
        s2.run();//子类重写了父类的方法,执行子类的方法
        s1.run();
        s1.eat();
    }
}

多态注意事项:

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类,有联系 类型转换异常!ClassCastExpection!看到这个说明父子类之间存在一些问题
  3. 存在条件:有继承关系,方法需要重写,父类引用指向子类对象!

​ static方法属于类,它不属于实例

​ final 常量

​ private修饰的方法,也不可以重写

这三个不能实现多态

instanceof

(类型转换)引用类型,判断一个对象是什么类型

System.out.println(X instanceof Y);

这个代码能不能编译通过,取决于X,Y之间是否存在父子关系

注意点:

  1. 父类引用指向子类对象
  2. 把子类转换为父亲,向上转型
  3. 把父类转换为子类,向下转型;强制转换
  4. 方便方法的调用,减少重复的代码!简洁
package OOP;

import OOP.demo6.Person;
import OOP.demo6.Student;
import OOP.demo6.Teancher;

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

        //类型之间的转换:  父     子
        //                高     低
        Person obj = new Student();

        //student将这个对象转换成Student类型,我们就可以使用Student类型的方法了!
        ((Student)obj).go();
        Student s1 = (Student) obj;
        s1.go();

        //子类转换为父类,可能会丢失自己本来的一些方法!
        Student student = new Student();
        student.go();
        Person person = student;
        

/*        Object object = new Student();

        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 Teancher);//False
        System.out.println(object instanceof String);//False
        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 Teancher);//False
        //System.out.println(person instanceof String);//编译报错!!!
        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 Teancher);//编译报错!!!
//        System.out.println(student instanceof String);//编译报错!!!
*/
    }
}
package OOP.demo6;

public class Student extends Person{
    public static void go(){
        System.out.println("go");
    }
}
package OOP.demo6;

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

static关键字详解

package OOP.demo7;

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(s1.score);
        System.out.println(s1.age);
    }
}
package OOP.demo7;

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 OOP.demo7;
//静态导入包
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);
    }
}

抽象

package OOP.demo8;

//抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类本身也是abstract
public class A extends Action{
    @Override
    public void doSomething() {

    }
}
package OOP.demo8;

//abstract 抽象类:类 extends: 单继承-,   接口可以多继承
public abstract class Action {
    //约束---有人帮我们实现
    //abstract , 抽象方法,只有方法的名字,没有方法的实现!
    public abstract void doSomething();

    //1.不能new出来抽象类,只能靠子类去实现它,约束!
    //2.抽象类中可以写普通方法
    public void hello(){

    }
    //3.抽象方法必须在抽象类中,也就是抽象类里面必须要有抽象方法
    //抽象的抽象:约束

    //思考:  new不出来,存在构造器吗?
    //抽象类存在的意义是什么?--------抽象出来~提高开发效率
}

接口

https://img.rruu.net/image/6041bcee2d143

声明类的关键字是class,声明接口的关键字是interface

接口作用:

  1. 是一种约束
  2. 定义一些方法,让不同的人实现 10----->1
  3. public abstract
  4. public static final
  5. 接口不能被实例化,接口中没有构造方法
  6. implements可以实现多个接口
  7. 必须要重写接口中的方法

内部类(奇葩的代码)

内部类就是在一个类的内部再定义一个类,比如,在A类中定义一个B类,那么B类相对于A类就称为内部类,而A类相对于B类来说就是外部类了。

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类
package OOP.demo10;

public class Outer {
    private int id = 10;
    public void out(){
        System.out.println("这是外部类的方法");
    }

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

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

    //局部内部类
    public void method(){
        class Ineeer{
            public void in(){

            }
        }
    }
}


//一个java文件中可以有多个class类,但是只能有一个public class
class A {
    public static void main(String[] args) {

    }
}
package OOP.demo10;

public class Test {
    public static void main(String[] args) {
    //没有名字初始化类, 不用将实例保存到变量中
        new Apple().eat();
        UserService userService = new UserService() {

        };
    }
}

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

interface UserService{

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

        Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();

        inner.getID();
posted @ 2021-03-05 13:46  Izereal  阅读(39)  评论(0)    收藏  举报