内部类

形式参数与返回值:

          形式参数的类型:1)基本类型:使用时没有什么区别,只要形参是什么类型就给它传什么类型的数据即可;

                                       2)引用类型:String特殊的引用类型,使用时与基本类型一致

                                                               (1)具体类:需要创建具体类的对象进行传值;

                                                               (2)抽象类:需要创建该抽象类的子类对象(抽象类多态,使用匿名内部类)

                                                               (3)接口类:需要创建该接口的子实现类(接口类多态,使用匿名内部类)

 

         返回值的类型:1)基本类型:需要返回什么数据类型就给返回什么数据类型;

                                  2)引用类型:(1)具体类:返回该具体类的对象;

                                                          (2)抽象类:返回该抽象类的子类对象;

                                                          (3)接口类:返回该接口的子实现类对象;

        

 内部类:在一个类(A)的内部定义另一个类(B),则B就是A的内部类

                   例:class A {

                                  private int num =  10;

                                  class  B {

                                     System.out.println(num);

                                 }

                          }

  内部类的访问特点:1)内部类可以访问外部类的成员,包括私有成员都可以访问;

                                  2)外部类想要访问内部类的成员时,需要创建内部类对象来访问内部类成员;

 

  内部类按所在的位置分类:

    1)成员内部类:存在于外部类的成员位置上;

             class A {

                                  private int num =  10;

                                (static) class  B {

                                     System.out.println(num);

                                 }

                          }

                        外部类访问成员内部类时创建对象的方法:

                                          (1)非静态内部类:外部类名 . 内部类名   对象名  =  new  外部类名().  new 内部类名();

                                                     例:A.B  ab =  new  A() . new B();

                                            (2)  静态内部类:外部类名 . 内部类名   对象名  =  new  外部类名 .  内部类名();

                                                                        外部类名.内部类名.(内部类)成员变量 / 方法

                                                     例: A.B  ab =  new  A.B (); 

                      成员内部类的修饰符:

                                  private 修饰:为了保证数据的安全性,只能通过在外部类的方法里创建内部类的对象进行访问;

                                  static   修饰:方便调用;可以通过 外部类名.内部类名. 成员变量/方法 直接调用

 

     2)局部内部类:存在于方法内的类;可直接访问外部类的成员,包括私有;

                例: 

             class A {

                                  private int num =  10;

                                  public void method(){

                                          final  int num2 = 20;  //JDK1.8以前必须使用 final 修饰,否则报错;

                                          class  B {

                                                   System.out.println(num);

                                                   System.out.println(num2);

                                          }

                                 }

                          }

    ***** 面试题:为什么要用 final 修饰局部变量?

          答:  局部内部类想要访问局部变量时,局部变量必须使用 final 修饰;

                   因为局部变量是随着方法的调用而存在的,随着方法的调用完毕而消失的,

                   而内部类对象在使用后却不会立即消被GC回收掉,

                   这时就会出现当方法调用完毕后,当局部内部类还需要访问该局部变量,所以程序就会报错,

                   所以这时就需要将局部变量变成常驻内存的变量(常量),所以用 final 修饰;

 

匿名内部类:顾名思义即没有名字的内部类;

         匿名内部类存在的前提:必须存在一个类 或者 接口

  格式:

              new  类名 / 接口名{

                      重写 类 或 接口中的方法;

                      。。。

              };逗号结尾

       

 *********匿名内部类面试题:
        按照要求,补齐代码
            interface Inter { 
                void show();
             }

            
            class Outer { 
                //补齐代码 

                Outer.method().show();

                // 分析 1)Outer.method() 外部类名可直接调用,说明该方法被 static 修饰;

                           2)Outer.method() 调用 method()后还能调用show()方法,说明返回的是一个对象(接口);

                         3)返回的是一个接口类型,实际返回的是的该接口的子实现类对象,根据题目要求应该采用匿名内部类来实现;

                  public static Inter method(){

                        return new Inter{     // 匿名内部类

                             @override

                             public void show(){

                                     System.out.println(" Hello  World");

                            }

                       };

                 }
            }
            class OuterDemo {
                public static void main(String[] args) {
                      Outer.method().show();
                  }
            }
            要求在控制台输出”HelloWorld”

 

**********面试题:
          控制台分包输出30,20,10

注意: 内部类与外部类之间没有继承关系!(无法用 super

外部类访问本类成员变量
            方式1:     外部类对象(匿名对象的方式).成员变量名称;
            方式2:     外部类的this限定:Outer.this.num:可以访问外部类的成员变量(推荐使用)

class Outer{
    
    private int num = 10 ;
    
    //成员内部类
    class Inner{
        //内部类的成员变量
        int num = 20 ;
        public void show() {
            //局部变量
            ( final ) int num = 30 ;
            //补全代码
             System.out.println(num);
             System.out.println(this.num); //访问当前类对象的成员变量
          // System.out.println(new Outer().num);
            
            //外部类限定this
            System.out.println(Outer.this.num);

        }
    }
}

public class OuterTest2 {
    public static void main(String[] args) {
        //补全代码
        //外部类名.内部类名 对象名 = 外部类对象.内部类对象;
        Outer.Inner oi = new Outer().new Inner() ;
        oi.show();

    }
}
 

常用类:

              1)Object类:所有类的根类,所有类都默认继承自Object类

                      常用方法: (1)public int hashCode():返回的是该对象的哈希码值(逻辑地址)

                                                  该哈希码值是根据对象的地址值计算而来的,一般来说不同对象的哈希值不同;

                                         (2)public final Class getClass(): 返回此对象的运行类

                                                        getClass().getName() : 可获得该运行类的全类名;(包名.类名)

                                         (3)public String toString(): 返回该对象的字符串表示(地址值);

                                                 相当于:getClass().getName()+@+Integer.toHexStirng(hashCode(此对象));

                                                默认输出是一个地址值,所以建议子类都重写该方法;

                                         (4)public  boolean equals(): 比较两对象是否相等;

                                          默认比较的是引用(地址值),所以建议子类重写该方法,重写之后比较的就是对象的内容是否相等

                                         (5)protected finalize(): 当垃圾回收机制确定该对象没有任何的引用之后,

                                               便会由对象的垃圾回收机制调用此方法进行回收;主要针对堆内存;

                                         (6)public Object clone(): 创建并返回该对象的一个副本(复制),

                                               这种克隆机制十分高效,且两个对象互相独立;

                                              前提: 该类必须实现 Cloneable 接口,才能调用此方法;                                                          

           自定义类实现克隆步骤:

                              A:自定义类实现Cloneable接口,这是一个标记性接口,实现这个接口的类的对象可以实现自我克隆。

                              B:自定义类中重写Object类的clone()方法。

                              C:重写clone()方法时通过 super.clone() 调用Object类的clone()方法来得到该对象的副本,并返回该副本。

 

           注意:

                        A:克隆和两个引用指向同一个对象的区别?

                        B:Objectclone()方法虽然简单,易用,但仅仅是一种浅克隆”,它只克隆该对象所有的Field值,

                          不会 对引用类型的Field所引用的对象进行克隆。开发中,我们也可以实现对象的深度克隆

 

*****面试题: ==  与 equals

       == :

                 基本数据类型:比较的是值;

                 引用类型:比较的是地址值;

       equals:

                 重写之前:Object类中equals()比较的是地址值;

                 重写之后:比较的是对象的“内容”,如String中的euqals()方法

 

       2)Scanner类:用于键盘录入

              常用方法:public XXX nextXXX() : 录入下一个XXX数据类型的数据
                                public boolean hasNextXXX(): 判断录入的数据下一个是否是XXX这类型的数据
 

               注意:     
                        // 先录入int类型的数据,在录入字符串 
                              int num = sc.nextInt() ;
                              Scanner sc2 = new Scanner(System.in) ;
                              String str = sc2.nextLine() ;
                              System.out.println("num:"+num+",str:"+str);
                                 会出现:输入数字后直接输回车它就直接打印出来了

                               //10
                              //num:10,str:

                       原因:系统默认把回车当作是一个字符串输入了,直接就略过了;但该字符串的长度为 0 ;

                       解决:在输入数字之后,再重新创建Scanner对象接收一次;

 

           3)String 类:由多个字符组成的一串字符,可以看成是一个字符数组

String:特殊的引用类型
            字符串是常量;一旦给它们赋值之后就不能更改。

            常量是在方法区中:字符串常量池  : 前提:将字符串常量直接赋值的形式 
             
          例:
                    String str = "abc" ;        ==>   相当于String str = new String("abc")

                
     构造方法:
          String() : 空参构造
          String(byte[] bytes): 将字节数组-->String 数据 
          String(byte[] bytes, int offset, int length): 将字节数组的一部分转换字符串
          String(char[] value) : 将字符数组转换成字符串
          String(char[] value, int offset, int length): 将字符数组的一部分转换字符串 
          public String(String original)    : 创建一个字符串对象:传递字符串常量
 
   常用的成员方法:
         
           public  int  length() :   获取字符串的长度;
           public boolean equals(Object anObject)    :  比较字符串的内容是否相同
           public boolean equalsIgnoreCase(String anotherString):   比较内容是否相同,忽略大小写
           public boolean contains(String s):   判断大字符串中是否包含一个子字符串
           public boolean startsWith(String prefix):   判断字符串是以...开头
           public boolean endsWith(String suffix):   判断字符串是以...结尾
           public boolean isEmpty() :   判断字符串是否为空


  两个区别:
           前者:表示当前s对象是一个空内容
           后者:表示空对象
            String s =""     ; str.length()=0
            String s = null ; 没有长度

******面试题

          String s = new String(“hello”)String s = “hello”;的区别?

                   答:String s = "hello" : 创建了一个对象;字符串常量池;

                          String s = new String(“hello”):创建了两个对象;堆内存和字符串常量池

         图解:

                

******笔试题    
            数组中有没有length(),字符串中有没有length(),集合中有没有length()?
                  数组length属性,字符串中有,集合没有-->size()方法
              

    注意:

    字符串变量相加,是先开辟空间(不是先相加),再看常量池中是否有这个字符串常量..
    字符串常量相加,是先拼接(先相加),再开辟空间


             String s7 = "hello";   // 存在于字符串常量池
             String s8 = "world";
             String s9 = "helloworld";
             System.out.println(s9==s7+s8);            //先开辟空间,再比较 flase
             System.out.println(s9.equals(s8+s7));  //先开辟空间,再比较 false
        
             String s10 = "helloworld";  // 存在于字符串常量池
             System.out.println(s10=="hello"+"world");            //先合并比较,再开辟空间  true
             System.out.println(s10.equals("hello"+"world"));   //先合并比较,再开辟空间  true

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值