[Java 06] 面向对象 2021.11.09 加油啊

面向对象


宏观上是通过分类的思维模式,进行分类,然后堆分类的问题单独思考。

思想: 抽象!!

Object-oriented Programming OOP

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

封装,继承,多态

1. 静态,非静态方法

class Student(){
    public static void a(){
        
    }
    public static void b(){
        
    }
}
// a 是 static, b 是 static
// a() 中可以 调用 b(), 两者都是在类创建的时候就存在了
// a 是 static , b 不是,
// a() 中不可以调用b(),因为b()在实例化的时候才存在,而a已经存在了
// a 不是 static, b 不是 static
//a() 中可以调用 b(), 俩这都在实例化的时候同时存在。

值传递和引用传递:

把 a= 1;传入函数,传入的是a的值,而不是a这个变量名,

把 person.name传入函数,传入的是这个变量的引用名,,引用传递。

2. 创建与初始化对象

使用new创建时,除了分配内存空间,对创建对象默认初始化,还有对类中的构造器进行调用。

构造方法的特点: 必须和类的名字相同,必须没有返回值也不写void

IDEA中查看已经预编译的class文件:

打开structure, module, 在add 目录下面导入out文件夹,就可以看到编译的class文件

定义了有参构造之后,想无参构造(返回null)必须写一遍无参构造的方法。(构造器可以重载的

快捷键:直接生成有参,无参构造:Alt + Insert,

3. 内存分析

java内存分析

4. 封装

属性私有,get/set

  1. 提高安全性,保护数据
  2. 隐藏代码的实现细节(在get,set里面可以加判断)
  3. 统一接口访问
  4. 系统可维护增加

快捷键: Alt + Insert ,可以generate get() and set()

public class Student{
    //属性私有
    private String name;
    private int id;
    private char sex;
    //get set 方法用于操作私有属性
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name; 
    }
}

5. 继承 extends

object, super, 重写 三块

1. object

快捷键:查看继承树: Ctrl + H

四种修饰符

public, protected, default, private

Student 要继承Person的属性,

  1. Person的属性时public
  2. Person的属性时private, 但提供方法可以访问(get, set)

Java中所有的class 都隐式的继承object类。


父类的private方法和属性不能被继承!!!

私有属性不能被继承

class Student extends Person{
    this.name; //调用自己的name
    super.name;//调用父类的name
}

2. super

调用this() 自己的构造器,也必须放在第一行(不能同时调用super构造和this构造)

public class Person{
    public Person(){
    }
}
//another file
public class Student extends Person{
    public Student(){
        super();//子类调用父类的构造器是隐藏的,如果要显式构造,则必须放置在第一句!!!
    }
}

3. 重写方法

快捷键: Alt + Insert , @override

  1. 有static, b对象调用的是B类的方法,所以输出和左边定义的数据类型有关。
class B{
    public static void test(){//注意都是static方法
        sout("B");
    }
}
class A extends B{
    public static void test(){
        sout("A");
    }
}
class Application{
    psvm{
        A a = new A();
        a.test();
        B b = new A();//重点:父类的引用指向了子类
        b.test();
    }
}
>>输出结果a.test()为A, b.test() 为B
  1. 没有static, 重写方法, b对象调用的是new A()时候的对象方法,所以输出为new A()的对象方法。
class B{
    public void test(){
        sout("B");
    }
}
class A extends B{
    @Override
    public void test(){
        sout("A");
    }
    public void test2(){
        sout("just A not B");
    }
}
class Application{
    psvm{
        A a = new A();
        a.test();
        B b = new A();//重点:父类的引用 指向了 子类
        b.test();
    }
}
>>输出结果a.test()为A, b.test() 为A
    b.test2()//无法访问,因为b还是B类型的对象。
  1. 总结:一个对象的实际类型是确定的

b在创建时,虽然new A(), 但A是继承B的,b向上转型为B(), 但使用new A()时的对象方法。而如果是父类B()中没有的方法如test2(),则b无法访问。

6. 多态

多态:父类的引用可以指向子类的实现

Student s1 = new Student();//一个对象的实际类型是确定的
Person s2 = new Student();//可以指向的引用类型就不确定了,引用类型是指左边的变量,父类的引用可以指向子类变量

如.5总结:

s1 是Student类,能调用的方法是自己的,或者继承的方法。

s2 是Person类,可以指向子类,但不能调用子类独有的方法。

对象能指向那些方法,主要看左边的对象类型,和右边关系不大。

多态是方法的多态,属性没有多态

7. instanceof关键字 类型转换

  1. 用来判断一个类是不是另一个类
sout(s1 instanceof Person);//返回True
  1. 强制转化(向下转型

    和基本类型强制转化一样,从高转低需要强制转换,低转高不需要(8字节转4字节需强制,4字节转8字节直接转)

    Person s1 = new Student();//低转高不需要强制转换
    Student s2  new Student();
    /*
    Person : run()
    Student: run(), go()
    */
    s1.go();//不可以执行,需要把s1强制转换为student类才可以用go方法。
    ((Student) s1).go();//可与执行
    

    子类转父类:(向上转型

    Person person = s2;//子类转父类会丢失方法(类似于精度问题)
    

8. Static 总结

  1. 已经会了

  2. 静态代码块,在类加载的时候执行,

    public class Student{
        {
            sout("匿名代码块");//在第二次加载类的时候也执行
        }
        static {
            sout("静态代码块");//这个是最先执行的,并且只执行一次
        }
        public Student(){
            sout("构造方法");
        }
    }
    >>(顺序) 静态代码块,匿名代码块, 构造方法
    
  3. final修饰的类,不能被继承,相当于被断了。

9. 抽象类

public abstract class Person{
    public abstract run();
}

不能new抽象类,只能靠子类实现,对子类约束

抽象方法必须在抽象类中

10. 接口(只有规范)

接口就是规范,定义的是一组规则。精髓? interface

public interface interfacename{
    //返回值类型  方法名称(参数)
    void run(String name);//方法前面的 public abstract 可以省略
    //只能写public abstract方法
}
public class xxxImpl implements interfacename{
    //具体实现,重写接口方法
    @Override
}

11. 内部类

一个java文件只能有一个public class, 但可以有多个class

  1. 内部类
public class Outer {
    private int id =10;
    public void out(){
        System.out.println("outer method");
    }
    class Inner{//定义内部类
        public void in(){
            System.out.println("inner method");
        }
        public void getID(){//内部类可以访问外部类的数据和方法
            System.out.println(id);
        }
    }
}
//another files
public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();//内部类的定义
        inner.in();
    }
  1. 静态内部类

    内部类的定义为 class static Inner{}, 不能访问id值,因为id在创建类的时候不存在,

  2. 局部内部类

    public class Outer{
        public void method(){
            class Inner{//方法里的类
                
            }
        }
    }
    
    
  3. 匿名类

    class Apple{}
    //使用:
    new Apple().eat();//直接调用类的方法
    
上一篇:2021-11-09


下一篇:CSP2017-09