Java面试题----面向对象

一、面向过程与面向对象

面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。而面向对象是模型化的,抽象出一个类,需要什么功能直接使用,不必知道这个功能如何实现、怎样实现;但面向对象的底层还是面向过程,把面向过程抽象成类,然后封装,方便我们使用。

二、Java面向对象三大特性

封装、继承、多态

封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性;

继承:提高代码复用性,继承是多态的前提;

多态:提高了程序的拓展性;

实现多态的两种形式:继承(多个子类对同一方法的重写)、接口(实现接口并覆盖接口中同一方法)

实现多态的三个必要条件:继承、重写、向上转型

三、抽象类与接口

相同点:1.接口和抽象类都不能实例化

              2.都位于继承的顶端,用于被其他类实现或继承

              3.都包含抽象方法,其子类都必须复写这些抽象方法

不同点:

参数抽象类接口
声明抽象类使用abstract关键字声明接口使用interface关键字声明
实现子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现
构造器抽象类可以有构造器接口不能有构造器
访问修饰符抽象类中的方法可以是任意访问修饰符接口方法默认修饰符是public。并且不允许定义为 private 或者 protected
多继承一个类最多只能继承一个抽象类一个类可以实现多个接口
字段声明抽象类的字段声明可以是任意的接口的字段默认都是 static 和 final 的
其他有构造方法、成员变量、常量、普通方法、抽象方法抽象方法、常量、普通方法(jdk1.8)

普通类和抽象类的区别:

  • 普通类不能包含抽象方法,抽象类可以包含抽象方法、普通方法
  • 普通类可以直接实例化,抽象类不能直接实例化
  • 抽象类不能被final修饰,因为定义抽象类就是为了让其他类继承

四、变量与方法

成员变量与局部变量区别

储存位置:

        成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中;

        局部变量:在方法被调用时或语句被执行时存在,当方法调用完后或语句执行完后就自动释放,存储在栈内存中

初始值: 

        成员变量:有默认初始值;

        局部变量:没有默认初始值,使用前必须赋值;

无参构造的作用:帮助子类做初始化工作

五、内部类

将一个类的定义放在另一个类的内部,即为内部类;内部类本身就是类的一个属性,与其他属性定义方式一致。

内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类

静态内部类:定义在类内部的静态类就是静态内部类。

public class Outer {
 
    private static int radius = 1;
 
    static class StaticInner {
        public void visit() {
            System.out.println("visit outer static  variable:" + radius);
        }
    }
}

静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量,静态内部类的创建方式:new 外部类.静态内部类(),如下

Outer.StaticInner inner = new Outer.StaticInner();
inner.visit();

成员内部类:定义在类的内部成员位置上的非静态类即为成员内部类,如下

public class Outer {
 
    private static  int radius = 1;
    private int count =2;
    
     class Inner {
        public void visit() {
            System.out.println("visit outer static  variable:" + radius);
            System.out.println("visit outer   variable:" + count);
        }
    }
}

成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,创建方式为:外部类实例.new 内部类(),如下:

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.visit();

局部内部类:定义在方法中的内部类即为局部内部类。

public class Outer {
 
    private  int out_a = 1;
    private static int STATIC_b = 2;
 
    public void testFunctionClass(){
        int inner_c =3;
        class Inner {
            private void fun(){
                System.out.println(out_a);
                System.out.println(STATIC_b);
                System.out.println(inner_c);
            }
        }
        Inner  inner = new Inner();
        inner.fun();
    }
    public static void testStaticFunctionClass(){
        int d =3;
        class Inner {
            private void fun(){
                // System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
                System.out.println(STATIC_b);
                System.out.println(d);
            }
        }
        Inner  inner = new Inner();
        inner.fun();
    }
}

定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类(),如下:

 public static void testStaticFunctionClass(){
    class Inner {
    }
    Inner  inner = new Inner();
 }

匿名内部类:匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

public class Outer {
 
    private void test(final int i) {
        new Service() {
            public void method() {
                for (int j = 0; j < i; j++) {
                    System.out.println("匿名内部类" );
                }
            }
        }.method();
    }
 }
 //匿名内部类必须继承或实现一个已有的接口 
 interface Service{
    void method();
}

匿名内部类创建方式:

new 类/接口{ 
  //匿名内部类实现部分
}

匿名内部类的特点:

  • 匿名内部类必须继承一个抽象类或者实现一个接口
  • 匿名内部类不能定义任何静态成员和静态方法
  • 当所在方法的形参需要被匿名内部类使用时,必须声明为final
  • 匿名内部类不能是抽象的,必须实现所继承类或实现接口的所有抽象方法

内部类的优点:

  • 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
  • 内部类不为同一包的其他类所见,具有很好的封装性;
  • 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
  • 匿名内部类可以很方便的定义回调。

局部内部类和匿名内部类访问局部变量时,为什么变量必须加上final?

public class Outer {
 
    void outMethod(){
        final int a =10;
        class Inner {
            void innerMethod(){
                System.out.println(a);
            }
 
        }
    }
}

为什么要加final呢?是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。

六、重写与重载

1.构造方法不能被继承,所以不能重写,可以被重载

2.方法的重写和重载都是实现多态的方式,区别在于重载实现的是编译时的多态性,而重写实现的是运行时的多态

3.重载:发生在同一个类中,方法名相同而参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,所以重载的方法不能根据返回类型区分

4.重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出异常小于等于父类,访问修饰符大于等于父类。(private和构造方法不能继承,static、final、private、构造方法不能重写)

七、对象相等判断

1)==和equals的区别

==的作用是判断两个对象的地址是不是相等,即判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)

equals()方法没有被重写时比较的是该类的两个对象,等价于==;重写后则比较两个对象的内容是否相等。

注:对象的相等与指向他们的引用相等有什么不同?

对象的相等,比较的是内存中存放的内容是否相等,而引用相等比较的则是他们指向的内存地址是否相等。

八、Java包

JDK中常用的包有哪些?

  • java.lang:这个是系统的基础类;
  • java.io:包含所有与输入输出有关的类,比如文件操作等;
  • java.nio:为了完善io包中的功能,提高io包中性能而写的一个新包;
  • java.net:包含与网络有关的类;
  • java.util:包含系统辅助类,特别是集合类;
  • java.sql:包含数据库操作的类;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值