前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字

Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字

作者头像
IBinary
发布2019-05-25 16:17:33
5570
发布2019-05-25 16:17:33
举报
文章被收录于专栏:逆向技术逆向技术

          Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字

一丶Java中包的机制

  首先包其实就是个文件夹.作用就是管理类. Java中每次定义一个类的时候.通过Java编译之后.都会生成一个扩展名为.class的文件.但是当这个程序规模逐渐庞大的时候.就很容易发生类名名称冲突的现象. 那么JDK API中. 提供了成千上万的具有各种功能的类.有效的管理就是通过类包来管理.

    1.类名冲突

      首先我们Java中可能定义一个A类.但是因为业务需要.还需要一个A类.名称一样,可能功能不一样.那么名字就会冲突.而Java编译器不允许存在同名的类文件.解决方法

就是放在不同的文件夹中(包中)

    2.完整的类路径

      在以前我们使用Math类.eclipse会自动引入一个包.关键字就是 import 包. 我们当时也不注意.反正能编写程序即可. 其实Math类.完整的路径是 Java.lang.math;

java.lang 是包的名称,可以理解为是文件夹. 后面的math是类名. 我们使用 import java.lang.Math 代表的意思就是 使用这个文件夹下指定的Math类.

我们如果不使用关键字 import引入包. 那么就要使用完整的类名 例如: java.lang.Math ma = new java.lang.Math();

注意:

    1.同一个包中的类互相访问的时候,可以不指定报名.

    2.同一个包中的类可以不用放在一个磁盘.什么意思. java.lang 是报名. 我们可以在D盘创建一个 java.lang E盘我们也创建一个java.lang 此时我们只需要CLASSPATH指向这两个包就行.包他认为就是一个.都属于java.lang包. 这跟文件夹不太一样.

  3.创建包.

我们可以使用Eclipse创建一个包. 新建->包. (new -> packet)

填写文件夹. 以及包名称即可.

创建完毕之后就有一个包了.在我们的项目中.

package 关键字

package 包名.

我们在类中指定包名的时候.需要将package表达是放置在程序的第一行. 他必须是文件中第一行.并且是非注释代码. 如果指定了包名称.那么代表这个类的完整路径就是

包名.类名称. 例如 com.aaa是我们的包. 在下面定义了一个类. Dog() 那么Dog类的完整路径就是 com.aaa.Dog();

例如:

  4.导入包

我们上边虽然定义了包.但是使用的时候我们必须指定完全的类名去创建对象.例如如下:

我们不能每次new对象的时候都要加上包的名称.所以我们可以使用关键字.导入包.这样使用的时候直接给定类名即可.

import关键字.

语法:

  import 包名.通配符.

例如: import com.xxx.Math 也可以 import com.xxx.*; 表示导入这个包中所有的类.

注意:如果你有两个相同类.你要使用那个类.就要加上完整的类名去使用. 这个便于区分. java中的类包.类似于C++的命名空间.都是解决冲突问题.

  5.Import的高级用法

Import不光可以导入类包.也可以导入静态变量.这个是 J2SE 5.0以上才支持的.

关键字:import static 包名+静态成员变量 代码如下.

二丶Final关键字的作用

  Final关键字是常量定义关键字. 他可以修饰类 方法. 以及变量跟引用.

变量:

    1.修饰变量

  1.修饰变量. 变量不可以修改.成了一个常量. 例如 final double PI = 3.14; 此时PI我们只可以访问而不能修改了.在修饰变量的时候应该直接进行初始化.

   C++ 则是在类外面加上类域进行初始化 const int 类名::变量 = 初始化的值;

  在Java类中如果只定义了final成员变量.那么初始化可以在构造函数中进行初始化.

  空白final成员变量初始化

  .2.final 修饰对象

    final修饰对象.则对象只能指定唯一的一个对象.且不能修改.

  如果修饰数组.则数组里面的值可以修改.但是数组对象不能指向别的数组了.

如下.:

   3.final与static的使用

    final 修饰的变量.初始化的时候可以使用随机数进行初始化.这样常量的值就是可以改变的.但是如果加上Static关键字.那么意思就是其内存区域是恒定不变的.所以值不会被改变了.

代码如下:

代码语言:javascript
复制
public class Cat {
    
    private static Random r = new Random();
    
    public final int a = r.nextInt(10);      //常量a
    public final static int b = r.nextInt(10);   //静态区域的常量b
    public Cat() {

    }
    public void eat() {
        System.out.println("猫在吃饭");
    };
}

使用

代码语言:javascript
复制
    public static void main(String[] args) {
        Cat c = new Cat();
        out.print("a = "  + c.a);
        out.println("  b  = "  + c.b);
        
        Cat b = new Cat();
        
        out.print("a = "  + b.a);
        out.print("  b  = "  + b.b);
    }

输出结果

可以看出.我们对象中final修饰的a也就是变量a随机数可以进行改变的.但是b因为是static所以不能被改变了.

在Java中 定义全局变量一般都是用 public static final 修饰. 这样修饰的只能在定义的时候并且初始化.可以这样使用.

方法:

   1.父类方法private + final修饰

以前我们知道.当父类中的方法 使用private修饰的时候.则子类继承父类的时候.则不能覆盖(重写)

而将方法使用final修饰的话.可以防止子类修改该类的定义与实现方式. 所以父类中使用private修饰的时候.

方法自然地加上了默认修饰符 final. 因为final修饰的方法效率远高于非final的方法.

注意下方代码:

父类:

代码语言:javascript
复制
 public   class  Anmail {

    final private void eat1() {
        System.out.println("父类吃1");
    }
    final public void eat2() {
        System.out.println("父类吃2");
    }
}

子类:

代码语言:javascript
复制
public class Dog extends Anmail implements IAnmail{

    public final void eat1() {
        System.out.println("子类吃1");
    }

    public final void eat2() {
        System.out.println("子类吃2");
    }
    
    
    @Override
    public void Play() {
        // TODO 自动生成的方法存根
        
    }

}

我们可以看到.我们子类竟然可以 "覆盖父类方法" 并且权限已经改为public 请注意.这个并不是覆盖.而是子类的一个新的方法.

跟父类的方法不一样.也没有进行重写.

final类

  final修饰的类则不能被继承了.

语法:

  final class 类名{}

三丶类的高级特性.内部类.

  在java中.类中可以使用内部类.意思就是在一个类中还可以定义一个类.

1.成员内部类

   成员内部类就是定义一个成员.这个成员就是一个内部类.

例如:

代码语言:javascript
复制
public class A{
   private class B{
       .....内部类代码.
   }  
}

其中 A是外部类. B是内部类.

B内部类可以随意使用外部类的成员变量以及成员方法. 不管这些类是否被修饰为private.

在外部类可以new 内部类.使用内部类.

例如:

代码语言:javascript
复制
public class A{
    class B{
       ....
     }
    B b = new B(); 使用内部类  
}

内部类的使用:

  内部类的实例化跟外部类一样.只不过你是内部类我们跟Java类包一样. 加上外部类名即可. 但是在new的时候有区别.

new的时候要在外部类中提供一个方法.这个方法专门是返回内部类的实例化对象.

代码语言:javascript
复制
public class Cat {
    
    public class Cat1{
        public int m_hande;
        public void eat() {
            System.out.println("内部类吃东西");
        }
    }
  Cat1 retInstance(){   //专门提供一个方法.进行返回成员内部类的实例化对象.
    return new Cat1();
}

}

使用:

代码语言:javascript
复制
public static void main(String[] args) {
        Cat c = new Cat();             //创建外部类对象
        Cat.Cat1 b = c.retInstance();  //外部类的方法返回内部类实例
        
        b.eat();
    }

或者使用以下方法.

代码语言:javascript
复制
public static void main(String[] args) {
        Cat c = new Cat();
        Cat.Cat1 b = c.new Cat1();//使用new
        
        b.eat();
    }

这里注意的就是一定要创建出外部类对象才可以使用内部类.

1.外部类方法返回内部类实例.

2.外部类中直接当成员使用.使用new的方法.new一个. 因为Cat1我们可以看成是一个成员变量.只不过是一个特殊的成员变量.

成员内部类的高级用法

  成员内部类可以向上转型为父类. 成员内部类可以实现一个接口.对外隐藏其实现方法.

例如如下; 定义接口:

代码语言:javascript
复制
public interface IAnmail {
    
    public abstract void Play(); //定义一个抽象方法
}

父类跟成员内部类

代码语言:javascript
复制
public class Cat {
    
    public class Cat1 implements IAnmail {

        @Override
        public void Play() {
            // TODO 自动生成的方法存根
            System.out.println("内部类玩耍");
        }  //实现IAnmail方法
        
    }
    public Cat1 retInstance(){   //专门提供一个方法.进行返回成员内部类的实例化对象.
        return new Cat1();
    }
}

可以看到.内部类Cat 实现了接口IAnmail. 并且外部类返回了内部类的实例化对象.

使用:

代码语言:javascript
复制
public static void main(String[] args) {
        Cat c = new Cat();
        IAnmail b  = c.retInstance();//注意此行代码
        b.Play();
        
    }

注意第二行代码:

代码语言:javascript
复制
.返回的是内部类实例化对象.使用接口接受.意思就是说向上转型为了父对象.父对象直接使用play方法. 这样可以隐藏内部类的实现细节. 其实本质区别没有变.还是类跟类的关系.
只不过是内部类而已.
这样做的好处是什么:  好处就是一般的类.不能多次实现接口中的方法. 而我们的内部类可以.我们可以写上几个内部类.去实现接口.并且多次实现其方法. 因为向上转型.会触发多态.
所以一个类中可以有不同的事件产生.这个一般用于窗口设计中.Android中好像也是这样.还没接触安卓.不过按照书上所写.应该可以同时监听不同的事件.

  this关键字用于内部类跟外部类

我们以前说过.this可以访问构造.也可以区分成员变量与局部变量的命名冲突. 但是此时我们的内部类中有成员的变量.跟外部类中的成员变量相同怎么办.

所以我们必须进行区别.

用一下代码进行区别.

代码语言:javascript
复制
public class Cat {
    int x = 0; //外部类的X
    public class Cat1   {
        int x = 1; //内部类的x
        public void eat(int x) {//方法中的形参x
            x ++ ; //操作的是方法中的形参x
            this.x ++; //操作的是内部类的x
            Cat.this.x++;//前边加上外部类名则是操作的外部类的成员变量x
            
        }
        public class cat2{
            int x;
            public void eat(int x) {
                x++;
                this.x++;
                Cat1.this.x ++;
                Cat.Cat1.this.x++;
            }
        }
    
    }
    public Cat1 retInstance(){   //专门提供一个方法.进行返回成员内部类的实例化对象.
        return new Cat1();
    }
}

首先总结来说.

this用于当前类.那么则是区分的本类的成员变量与形参.

如果this前边加上父类名. 则是操作的父类的成员变量.

下面我们写了内部类的内部类. 使用this的时候就是 都是加外部类名. 只不过类名不一样而已. 依次类推.

2.方法内部类 /局部内部类.

  方法内部类就是说.可以定一个方法.这个方法中可以定义一个类去使用.

因为他是属于一个方法的.是一个方法中的类.所以外部类不可以访问局部内部类. 但是内部类可以访问当前代码块的常量以及外部类的所有成员.

代码如下:

代码语言:javascript
复制
public class Cat {
    int x = 0; //外部类的X

    public IAnmail retInstance(){   //专门提供一个方法.进行返回成员内部类的实例化对象.
            
        class Cat1 implements IAnmail{

    
            public void Play() {
            // TODO 自动生成的方法存根
                System.out.println("内部进行玩耍");
            }
            
        }
        return new Cat1(); //返回实例化对象.但是需要用父类进行接收.因为外部没有此类对象
    }
}

使用:

代码语言:javascript
复制
public static void main(String[] args) {
        Cat c = new Cat();
        IAnmail b  = c.retInstance();
        b.Play();
        
    }

局部内部类很简单.就是方法中定义一个类.而返回的时候可以返回这个类的实例对象.使用父类接受.可以向上转型.

3.匿名内部类.

  上面所说的局部内部类.返回的时候是自己new了一个对象进行返回.且外面进行接受了. 我们还可以使用return的时候.字节返回.

就不用类定义了.

代码如下:

代码语言:javascript
复制
public class Cat {
    int x = 0; //外部类的X

    public IAnmail retInstance(){
        
            
        return new IAnmail() {

            @Override
            public void Play() {
                // TODO 自动生成的方法存根
                System.out.println("匿名内部类");
            }
            
        };
    }
}

匿名内部类就是跟return语句进行结合了. 还是在方法内部.

以前我们返回的是 new Cat1(); 现在我们知道返回值是一个接口.我们可以直接返回一个接口类.

其实这个类的作用就是返回一个实现接口的对象而已.

语 法: new A () {

....

}

A可以是一个接口. 父类. 向上转型类都可以.

4.静态内部类.

  在内部类前边添加修饰符static.那么就是静态内部类. 静态内部类中可以声明static成员.但是不是静态内部类不可以声明静态成员.

特点: 不可以使用外部类的非静态成员. 所以静态内部类开发中很少见.

可以理解为静态内部类加了很多现实.

1.如果创建静态内部类的对象.不需要其他外部类的对象.

2.不能从静态内部类的对象中访问非静态外部类的对象.

5.内部类的继承

  如果一个类.想要继承一个内部类.

比如有一个A类.一个B类. B类中有内部类C类.

我们的A类想要继承B中的C类.

那么A类就要提供一个带参构造. 参数是类 B.

且构造参数中需要加上a.super():才可以.

代码如下.

代码语言:javascript
复制
 public   class  AnmailB {

     public class AnmailC{
         
     }
}

使用一个类继承AnmailC

代码语言:javascript
复制
public class Cat  extends AnmailB.AnmailC{
    public Cat( AnmailB b) {
        b.super();
    }
    
}

四丶总结

    1).Java中的类包

      package 包名 用来定义一个包

      import 包名.类名 导入一个包中的某个类. 可以直接使用这个类new对象了.而不用加上完整包路径

    2).java中的final变量

      final 修饰变量 变量变量变成常量.且不能修改

      final 修饰引用. 引用只能指向一个对象.不能更改指向. 但是引用里面的成员变量的值可以修改.

      final 修饰数组. 数组里面的值可以改变.地址不能改变了.意思就是不能更改指向了.

      final 跟 static一起使用 final 修饰常量.可以被随机数修改值.也就是初始化的时候. 但是加上static则内存是一块不能改变的. 也就是说值被赋值之后.内存里面的值不会在进行改变了.

      final 修饰方法. 则方法不能被继承跟重写. private权限.默认加了final关键字.

    3).java中的内部类.

    1.成员内部类.

      成员内部类就是一个成员. 使用的时候外部类提供方法.用来返回内部类的实例化对象.

       A.B a = A.retInstance(); 或者 A.B a = A.new B();

      成员内部类可以实现接口. 返回的时候可以使用父类接受. 向上转型.隐藏实现细节.

      接口 A = A.new B(); 内部类可以实现多个接口中方法.用来监听不同的事件.

    2.局部内部类,方法内部类.

      定义一个方法.方法中定义一个类.返回的时候可以返回这个类的实例化对象. 返回值可以是 实现的接口.或者父类.向上转型.

    3.匿名内部类. 

      匿名内部类直接返回一个实现接口的对象即可.

      例如 return new 接口(){ xxx代码};

    4.静态内部类.

      静态内部类就是给类加了限制.不能访问外部类的非静态成员. 内部类中只能定义静态成员.

    4).this关键字用于内部类

      this关键字用于类内部可以区分类的成员变量跟形参区别.

      如果想使用外部类.则要加上外部类的类名才可以 外部类名.this.成员变量; 这样使用的就是外部类的成员

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •           Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字
    • 一丶Java中包的机制
      •     1.类名冲突
      •     2.完整的类路径
      •   3.创建包.
      •   4.导入包
      •   5.Import的高级用法
    • 二丶Final关键字的作用
      • 变量:
      • 方法:
      • final类
    • 三丶类的高级特性.内部类.
      • 1.成员内部类
      • 成员内部类的高级用法
      •   this关键字用于内部类跟外部类
      • 2.方法内部类 /局部内部类.
      • 3.匿名内部类.
      • 4.静态内部类.
      • 5.内部类的继承
    • 四丶总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档