Java面向对象

这篇博客详细介绍了Java的面向对象特性,包括方法重载、类、构造方法、this关键字、继承、super关键字、多态等核心概念,同时也涵盖了静态、final、抽象类和接口等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.方法重载(overload/overloading):

2.类:是一种引用数据类型

3.默认值规则:

4.构造方法:构造函数、构造器、构建器----复用给成员变量赋初值的代码

5.this的用法

6.null:表示空,没有指向任何对象

7.引用类数组:

8.继承:

9.super:指代当前对象的超类对象

10.向上造型(多态):

11.方法的重写(override/overriding):

12.package和import

13.访问控制修饰符

14.static:静态的

        静态变量:

        静态方法:

        静态块:

15.final:最终的、不可改变的

16.抽象方法:

17.抽象类:

18.成员内部类

19.匿名内部类

20.接口

21.多态

22.内存管理:由JVM管理的

23.面向对象三大特征总结:   


1.方法重载(overload/overloading):

        发生在同一类中,方法名称相同,参数列表不同

        编译器在编译时会根据方法的签名自动绑定方法

2.类:是一种引用数据类型

          引用
数据类型 引用类型变量 指向     对象
Student    zs       = new Student();//创建一个Student型的引用zs,指向了一个学生对象

3.默认值规则:

byte,short,int,long,char----------------0
float,double----------------------------0.0
boolean---------------------------------false
引用类型---------------------------------null

方法的签名:方法名+参数列表

4.构造方法:构造函数、构造器、构建器----复用给成员变量赋初值的代码

        作用:给成员变量赋初始值

        语法:与类同名,没有返回类型(连void都没有)

        调用:在创建(new)对象时被自动调用

        若自己不写构造方法,则编译器默认提供一个无参构造方法,若自己写了构造方法,则不再默认提供

        构造方法可以重载

5.this的用法

        指代当前对象,哪个对象调用方法它指的就是哪个对象;只能用在方法中,方法中访问成员变量之前默认有个this

        this.成员变量名----------访问成员变量

注:当成员变量与局部变量同名时,若想访问成员变量,则this不能省

        this.方法名()----------调用方法(一般不这么写)

        this()--------------------调用构造方法(一般很少用)

6.null:表示空,没有指向任何对象

        如引用的值为null,则该引用不能再进行任何操作了,若操作则发生NullPointerException空指针异常

注:1.java规定:成员变量和局部变量是可以同名的,使用的时候默认采取就近原则

       2.基本类型变量中存储的就是具体的数,引用类型变量中存储的是对应对象的地址

       3.成员变量:写在类中,方法外,在整个类中好使

          局部变量:写在方法中,当前方法中使用

7.引用类数组:

        引用类型数组和基本类型数组的区别:

        区别1:给引用类型数组的元素赋值时,需要new个对象

        区别2:若想访问引用类型数组元素的数据,需要通过数组元素去打点

8.继承:

        作用:代码复用

        继承一定要符合is(是)的关系,通过extends来实现继承

        超类/父类:共有的属性和行为

        派生类/子类:特有的属性和行为

        派生类可以访问派生类的也可以访问超类的,但超类不能访问派生类的

        一个超类可以有多个派生类,但一个派生类只能有一个超类---------单一继承

        具有传递性

        java规定:构造派生类之前必须构造超类

        在派生类构造方法中自己没有调用超类构造方法,则默认super()调用超类无参构造方法

        在派生类构造方法中若自己调用了超类构造方法,则不再默认提供

        注:super()调用超类构造方法,必须位于派生类构造方法的第一行

9.super:指代当前对象的超类对象

        super的用法:

        super.成员变量名----------访问超类的成员变量

        super.方法名()--------------调用超类的方法

        super()------------------------调用超类的构造方法

        注:当超类的成员变量与派生类的成员变量同名时,若不写super或this,则默认就近原则(默认访问的是派生类的成员变量)。若想访问超类的成员变量,必须用super.成员变量名

10.向上造型(多态):

        超类型的引用指向了派生类的对象

1.多种角色干的事都一样的时候,可以将那多种角色统一造型到超类数组中,实现代码复用

2.将超类作为参数或返回值类型,传递派生类对象或返回派生类对象,也是在复用代码

public class ExtendsDemo {
    public static void main(String[] args) {
        Aoo o1 = new Aoo();
        o1.a = 1;
        o1.show();
        //o1.b = 2;  //编译错误
        //o1.test(); //编译错误,超类不能访问派生类的

        Boo o2 = new Boo();
        o2.b = 1;
        o2.test();
        o2.a = 2;  //正确
        o2.show(); //正确,派生类可以访问超类的

        //能点出来什么,看引用的类型------------------这是规定,记住就OK了
        Aoo o3 = new Boo(); //向上造型
        o3.a = 1;
        o3.show();
        //o3.b = 2;  //编译错误
        //o3.test(); //编译错误,能点出来什么,看引用的类型
    }
}
class Aoo{
    int a;
    void show(){
    }
}
class Boo extends Aoo{
    int b;
    void test(){
    }
}

11.方法的重写(override/overriding):

        发生在父子类中,方法名相同,参数列表相同

        重写方法被调用时,看对象的类型

        重写的原则(两同两小一大):

                两同:方法名相同,参数列表相同

                两小:派生类方法的返回值类型小于或等于超类方法的返回类型

                                void和基本类型时,必须相等

                                引用类型时,小于或等于

                        派生类方法抛出的异常小于或等于超类方法的

                一大:派生类方法的访问权限大于或等于超类方法的

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

    }
}

//超类大,派生类小
class Aoo{
    void show(){}
    double test(){ return 0.0; }
    Boo say(){ return null; }
    Aoo sayHi(){ return null; }
}
class Boo {
    //int show(){ return 1; } //编译错误,void时必须相等
    //int test(){ return 0; } //编译错误,基本类型时必须相等
    //Aoo say(){ return null; } //编译错误,引用类型时必须小于或等于
    Boo sayHi(){ return null; } //正确,Boo小于Aoo
}

12.package和import

        package:声明包

                作用:避免类的命名冲突

                同包中的类不能同名,但是不同包中的类可以同名

                类的全称:包名.类名

                建议:包名所有字母都小写,并且常常有层次结构

        import:导入类

                同包中的类可以直接访问,但不同包中的类不能直接访问,若想访问:

                        先import导入类,再访问类------建议

                        类的全称------------------------------繁琐

13.访问控制修饰符

        public:公开的,任何类

        private:私有的,本类

        protected:受保护的,本类,派生类,同包类

        默认的:本类,同包类--------------------------java不建议默认权限

访问控制修饰符的访问权限由低到高依次为:private<默认的<protected<public

package ooday04;
//演示访问控制修饰符
public class Coo {
    public int a;    //任何类
    protected int b; //本类、派生类、同包类
    int c;           //本类、同包类
    private int d;   //本类

    void show(){
        a = 1;
        b = 2;
        c = 3;
        d = 4;
    }
}

class Doo{ //-------------------演示private
    void show(){
        Coo o = new Coo();
        o.a = 1;
        o.b = 2;
        o.c = 3;
        //o.d = 4; //编译错误
    }
}

package ooday04_vis;
import ooday04.Coo;
public class Eoo { //-----------------演示同包的
    void show(){
        Coo o = new Coo();
        o.a = 1;
        //o.b = 2; //编译错误
        //o.c = 3; //编译错误
        //o.d = 4; //编译错误
    }
}

class Foo extends Coo{ //跨包继承-----------演示protected
    void show(){
        a = 1;
        b = 2;
        //c = 3; //编译错误
        //d = 4; //编译错误
    }
}

14.static:静态的

        静态变量:

                由static修饰

                属于类,存储在方法区中,只有一份

                常常通过类名点来访问

                何时用:所有对象所共享的数据(图片,音频,视频等)

package ooday04;
//static的演示
public class StaticDemo {
    public static void main(String[] args) {
        Foo o1 = new Foo();
        o1.show();
        Foo o2 = new Foo();
        o2.show();
        Foo o3 = new Foo();
        o3.show();
        System.out.println(Foo.b); //常常通过类名点来访问
    }
}
//演示静态变量
class Foo{
    int a; //实例变量
    static int b; //静态变量
    Foo(){
        a++;      //今天晚上的晚课,暂停一次
        b++;
    }
    void show(){
        System.out.println("a="+a+",b="+b);
    }
}

        静态方法:

                由static修饰

                属于类,存储在方法区中,只有一份

                常常通过类名点来访问

                静态方法中没有隐士this传递,所以不能直接访问实例成员

                何时用:方法的操作与对象无关

package ooday04;
//static的演示
public class StaticDemo {
    public static void main(String[] args) {
        int num = Hoo.plus(5,6); //常常通过类名点来访问
    }
}

//演示静态方法何时用
class Hoo{
    int a; //描述的是对象的属性
    //show()中需要访问对象的属性,说明show()方法与对象有关,所以不能设计为静态方法
    void show(){
        System.out.println(a);
    }
    //plus()中不需要访问对象的属性,说明plus()方法与对象无关,所以可以设计为静态方法
    static int plus(int num1,int num2){
        int num = num1+num2;
        return num;
    }
}

//演示静态方法
class Goo{
    int a; //实例变量(通过对象来访问)
    static int b; //静态变量(通过类名来访问)
    void show(){ //有隐式this
        System.out.println(this.a);
        System.out.println(Goo.b);
    }
    static void test(){ //没有隐式this
        //静态方法中没有隐式this传递
        //没有this就意味着没有对象
        //而实例变量a必须通过对象来访问
        //所以如下语句发生编译错误
        //System.out.println(a); //编译错误
        System.out.println(Goo.b);
    }
}

        静态块:

                由static修饰

                属于类,在类被加载期间自动执行,一个类只被加载一次,所以静态块只执行一次

                何时用:初始化/加载静态资源(图片、图片、视频)

package ooday04;
//static的演示
public class StaticDemo {
    public static void main(String[] args) {
        Ioo o4 = new Ioo();
        Ioo o5 = new Ioo();
        Ioo o6 = new Ioo();
    }
}

//演示静态块
class Ioo{
    static {
        System.out.println("静态块");
    }
    Ioo(){
        System.out.println("构造方法");
    }
}

数据(成员变量)私有化(private),行为(方法)大部分都公开化(public)

成员变量分两种:

        实例变量:没有static修饰,属于对象的,存储在堆中,有几个对象就有几分,通过引用名(对象)打点来访问

        静态变量:有static修饰,属于类,存储在方法区中,只有一份,通过类名打点来访问

内存管理:由JVM管理的

        堆:new出来的对象(包括实例变量、数组的元素)

        栈:局部变量(包括方法的参数)

        方法区:.class字节码文件(包括静态变量、所有方法)

15.final:最终的、不可改变的

        修饰变量:变量不能改变

        修饰方法:方法不能被重写

        修饰类:类不能被继承

        static final常量:

                必须声明同时初始化

                常常由所有类名来访问,不能被改变

                建议:常量名所有字母都大写,多个单词用下划线(_)分隔

                编译器在编译时会将常量直接替换为具体的数,效率高

                何时用:程序运行过程中数据永远不变,并且经常使用

public class StaticFinalDemo {
    public static void main(String[] args) {
        System.out.println(Hoo.PI); //常常由类名点来访问
        //Hoo.PI = 3.1415926; //编译错误,常量不能被改变
		
        //1)加载Ioo.class到方法区中
        //2)静态变量num一并存储到方法区中
        //3)到方法区中获取num的值并输出
        System.out.println(Ioo.num);

        //编译器在编译时会将常量直接替换为具体的数,效率高
        //相当于System.out.println(5);
        System.out.println(Ioo.COUNT);
    }
}

class Ioo{
    public static int num = 5; //静态变量
    public static final int COUNT = 5; //常量
}

class Hoo{
    public static final double PI = 3.1415926;
    //public static final int NUM; //编译错误,常量必须声明同时初始化
}

16.抽象方法:

        由abstract修饰

        只有方法的定义,没有具体的实现(连{}都没有)

17.抽象类:

       abstract修饰

        包含抽象方法的类必须是抽象类

        抽象类不能被实例化(new对象)

        抽象类是需要被继承的,派生类

                重写所有抽象方法

                也设计为抽象类

        抽象类的意义:

                封装共有的属性和行为

                为所有派生类提供统一的类型----向上造型

                可以包含抽象方法,为所有派生类提供统一的入口,同时达到强制重写的目的

        抽象方法/抽象类的疑问:

                抽象方法的意义:

                        保证当发生向上造型时,通过超类的引用能点出那个方法来

                既然抽象方法的意义是保证能点出来,为什么不设计为普通方法呢?

                        设计为普通方法,意味着派生类可以重写也可以不重写,但设计为抽象方法,

                        则可以强制派生类必须重写,以达到统一的目的

        含抽象方法的类一定是抽象类,不含抽象方法的类也可以是抽象类,

        abstract和final不能同时修饰一个类

18.成员内部类

        类中套类,外面的称为外部类,里面的称为内部类

        内部类通常只服务于外部类,对外不具备可见性

        内部类对象通常只在外部类中创建

        内部类中可以直接访问外部类的成员(包括私有的)

        内部类中有一个隐式的引用指向了创建它的外部类对象------外部类名.this

        何时用:有一个类A,只能被另一个类B使用,并且还想访问类B的成员,可以设计为成员内部类

隐式的引用:

        this:指代当前对象

        super:指代当前对象的超类对象

        外部类名.this:指代当前对象的外部类对象

public class InnerClassDemo {
    public static void main(String[] args) {
        Mama m = new Mama();
        //Baby b = new Baby(); //编译错误,Baby类对外不可见
    }
}

class Mama{ //外部类
    private String name;
    void create(){
        Baby b = new Baby(); //正确
    }
    class Baby{ //内部类
        void showName(){
            System.out.println(name); //简写
            System.out.println(Mama.this.name); //完整写法--Mama.this指Mama对象
            //System.out.println(this.name); //编译错误,this指Baby对象
        }
    }
}

19.匿名内部类

        何时用:若想创建一个类(派生类)的对象,并且对象只被创建一次,可以设计为匿名内部类

        匿名内部类中不能修改外面局部变量的值,因为在此处该变量默认为final

内部类有独立的.class字节码文件吗?-------有

方法的调用:

        同一类中的方法,可以直接写方法名调用

        不同类中的方法:

                若为实例方法(没有static), 则通过引用变量调用

                若为静态方法(有static),则通过类名调用

public class NstInnerClassDemo {
    public static void main(String[] args) {
        //1)创建了Aoo的一个派生类,但是没有名字
        //2)为该派生类创建了一个对象,名为o1,向上造型为Aoo类型
        //  ---new Aoo(){}是在创建Aoo的派生类的对象
        //3)大括号中的为派生类的类体
        Aoo o1 = new Aoo(){
        };

        //1)创建了Aoo的一个派生类,但是没有名字
        //2)为该派生类创建了一个对象,名为o2,向上造型为Aoo类型
        //  ---new Aoo(){}是在创建Aoo的派生类的对象
        //3)大括号中的为派生类的类体
        Aoo o2 = new Aoo(){
        };

        int num = 5;
        num = 55;
        //1)创建了Boo的一个派生类,但是没有名字
        //2)为该派生类创建了一个对象,名为o3,向上造型为Boo类型
        //3)大括号中的为派生类的类体
        Boo o3 = new Boo(){
            void show(){
                System.out.println("showshow");
                //num = 66; //编译错误,num在此处默认为final的,所以不能修改
            }
        };
        o3.show();
    }
}

abstract class Boo{
    abstract void show();
}

abstract class Aoo{
}

20.接口

        是一种引用数据类型

        由interface定义

        只能包含常量和抽象方法(数据默认都是常量,方法默认都是抽象的),权限只能是public

interface Inter{ //接口中成员的访问权限只能是public(默认也是public)
    public static final int NUM = 5;
    public abstract void show();
    int COUNT = 6; //默认public static final
    void test(); //默认public abstract
    //int number; //编译错误,常量必须声明同时初始化
    //void say(){} //编译错误,抽象方法不能方法体
}

        接口不能被实例化(new对象)

        接口是需要被实现/继承的,实现类/派生类:必须重写所有抽象方法

interface Inter1{
    void show();
    void test();
}
class Aoo implements Inter1{
    public void show(){} //重写接口中的抽象方法时,必须加public
    public void test(){}
}

        一个类可以实现多个接口,用逗号分隔。若又继承又实现时,应先继承后实现

interface Inter2{
    void show();
}
interface Inter3{
    void test();
}
abstract class Boo{
    abstract void say();
}
class Coo extends Boo implements Inter2,Inter3{
    public void show(){}
    public void test(){}
    void say(){}
}

        接口可以继承接口

interface Inter4{
    void show();
}
interface Inter5 extends Inter4{
    void test();
}
class Doo implements Inter5{
    public void test(){}
    public void show(){}
}

public class InterfaceDemo {
    public static void main(String[] args) {
        //Inter5 o1 = new Inter5(); //编译错误,接口不能被实例化
        Inter5 o2 = new Doo(); //向上造型
        Inter4 o3 = new Doo(); //向上造型
    }
}

类接口关系:

        类与类--------------------------继承extends

        接口和接口--------------------继承extends

        类和接口-----------------------实现implements

21.多态

        表现:同一个对象被造型为不同的类型时,有不同的功能----------所有对象都是多态的

                同一类型的引用指向不同的对象时,有不同的实现-----------所有抽象方法都是多态的

        向上造型/自动类型转换:

                超类型的引用指向派生类的对象

                能点出来什么,看引用的类型

                能向上造型成为的类型有:超类+所有实现的接口

        向下转型/强制类型转换,成功的条件只有如下两种:

                引用所指向的对象,就是该类型

                引用所指向的对象,实现了该接口或继承了该类

        强转时若不符合如上条件,则发生ClassCastException类型转换异常

        建议:在强转之前先通过instanceof判断引用指向的对象是否是该类型

注意:1.instanceof返回boolean结果,它为true的条件与强转成功的条件是一样的

           2.何时需要强转:若想访问的变量/方法在超类中没有,则需要强转

public class MultiTypeDemo {
    public static void main(String[] args) {
        //条件1: 引用所指向的对象,就是该类型
        //条件2: 引用所指向的对象,实现了该接口或继承了该类
        Aoo o = new Boo(); //向上造型
        Boo o1 = (Boo)o;     //引用o所指向的对象,就是Boo类型-------符合条件1
        Inter o2 = (Inter)o; //引用o所指向的对象,实现了Inter接口---符合条件2
        //Coo o3 = (Coo)o; //运行时会发生类型转换异常
        if(o instanceof Coo){ //false
            Coo o4 = (Coo)o;
        }else{
            System.out.println("o不是Coo类型");
        }
        //System.out.println(o instanceof Boo);   //true
        //System.out.println(o instanceof Inter); //true
        //System.out.println(o instanceof Coo);   //false
    }
}

interface Inter{ } //大
class Aoo{ } //大
class Boo extends Aoo implements Inter{ } //小
class Coo extends Aoo{ } //小

22.内存管理:由JVM管理的

        堆:存储new出来的对象(包括实例变量、数组的元素)

               垃圾:没有任何引用所指向的对象

               垃圾回收器(GC)不定时到内存堆中清扫垃圾,回收过程是透明的,不一定一发现垃圾

               就立刻回收,通过调用System.gc()可以建议JVM尽快调度GC来回收。

               实例变量的生命周期:创建对象时存储在堆中,对象被回收时一并回收

               内存泄漏:不再使用的对象还没有被及时的回收,严重的泄露会导致系统的崩溃

               建议:不再使用的对象应及时将引用设置为null

        栈|:存储正在调用的方法中的局部变量(包括方法的参数)

               调用方法时,会在栈中为该方法分配一块对应的栈帧,栈帧中存储局部变量(方法的

               参数),方法调用结束时,栈帧被自动清除,局部变量一并被清除

                局部变量的生命周期:调用方法时存储在栈中,方法调用结束时与栈帧一并被清除

        方法区:存储.class字节码文件(包括静态变量、所有方法)

                方法只有一份,通过this来区分具体的调用对象 

23.面向对象三大特征总结:   

        封装:类:封装的是对象的属性和行为

                   方法:封装的是具体的业务逻辑功能实现

                   访问控制修饰符:封装的是具体的访问权限,隐藏数据,暴露功能

        继承:作用:代码复用

                   超类:所有派生类所共有的属性和行为

                   接口:部分派生类所共有的属性和行为

                   派生类:派生类所特有的属性和行为

                   特点:单一继承、多接口实现、具有传递性

        多态:多种形态

                   所有对象都是多态的-----------------------------------通过向上造型来体现

                   所有抽象方法都是多态的-----------------------------通过方法的重写来体现

                   向上造型、向下转型(强制类型转换)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值