Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字
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关键字.那么意思就是其内存区域是恒定不变的.所以值不会被改变了.
代码如下:
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("猫在吃饭");
};
}
使用
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的方法.
注意下方代码:
父类:
public class Anmail { final private void eat1() {
System.out.println("父类吃1");
}
final public void eat2() {
System.out.println("父类吃2");
}
}
子类:
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.成员内部类
成员内部类就是定义一个成员.这个成员就是一个内部类.
例如:
public class A{
private class B{
.....内部类代码.
}
}
其中 A是外部类. B是内部类.
B内部类可以随意使用外部类的成员变量以及成员方法. 不管这些类是否被修饰为private.
在外部类可以new 内部类.使用内部类.
例如:
public class A{
class B{
....
}
B b = new B(); 使用内部类
}
内部类的使用:
内部类的实例化跟外部类一样.只不过你是内部类我们跟Java类包一样. 加上外部类名即可. 但是在new的时候有区别.
new的时候要在外部类中提供一个方法.这个方法专门是返回内部类的实例化对象.
public class Cat { public class Cat1{
public int m_hande;
public void eat() {
System.out.println("内部类吃东西");
}
}
Cat1 retInstance(){ //专门提供一个方法.进行返回成员内部类的实例化对象.
return new Cat1();
}
}
使用:
public static void main(String[] args) {
Cat c = new Cat(); //创建外部类对象
Cat.Cat1 b = c.retInstance(); //外部类的方法返回内部类实例 b.eat();
}
或者使用以下方法.
public static void main(String[] args) {
Cat c = new Cat();
Cat.Cat1 b = c.new Cat1();//使用new b.eat();
}
这里注意的就是一定要创建出外部类对象才可以使用内部类.
1.外部类方法返回内部类实例.
2.外部类中直接当成员使用.使用new的方法.new一个. 因为Cat1我们可以看成是一个成员变量.只不过是一个特殊的成员变量.
成员内部类的高级用法
成员内部类可以向上转型为父类. 成员内部类可以实现一个接口.对外隐藏其实现方法.
例如如下;
定义接口:
public interface IAnmail { public abstract void Play(); //定义一个抽象方法
}
父类跟成员内部类
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. 并且外部类返回了内部类的实例化对象.
使用:
public static void main(String[] args) {
Cat c = new Cat();
IAnmail b = c.retInstance();//注意此行代码
b.Play(); }
注意第二行代码:
.返回的是内部类实例化对象.使用接口接受.意思就是说向上转型为了父对象.父对象直接使用play方法. 这样可以隐藏内部类的实现细节. 其实本质区别没有变.还是类跟类的关系.
只不过是内部类而已.
这样做的好处是什么: 好处就是一般的类.不能多次实现接口中的方法. 而我们的内部类可以.我们可以写上几个内部类.去实现接口.并且多次实现其方法. 因为向上转型.会触发多态.
所以一个类中可以有不同的事件产生.这个一般用于窗口设计中.Android中好像也是这样.还没接触安卓.不过按照书上所写.应该可以同时监听不同的事件.
this关键字用于内部类跟外部类
我们以前说过.this可以访问构造.也可以区分成员变量与局部变量的命名冲突. 但是此时我们的内部类中有成员的变量.跟外部类中的成员变量相同怎么办.
所以我们必须进行区别.
用一下代码进行区别.
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.方法内部类 /局部内部类.
方法内部类就是说.可以定一个方法.这个方法中可以定义一个类去使用.
因为他是属于一个方法的.是一个方法中的类.所以外部类不可以访问局部内部类. 但是内部类可以访问当前代码块的常量以及外部类的所有成员.
代码如下:
public class Cat {
int x = 0; //外部类的X public IAnmail retInstance(){ //专门提供一个方法.进行返回成员内部类的实例化对象. class Cat1 implements IAnmail{ public void Play() {
// TODO 自动生成的方法存根
System.out.println("内部进行玩耍");
} }
return new Cat1(); //返回实例化对象.但是需要用父类进行接收.因为外部没有此类对象
}
}
使用:
public static void main(String[] args) {
Cat c = new Cat();
IAnmail b = c.retInstance();
b.Play(); }
局部内部类很简单.就是方法中定义一个类.而返回的时候可以返回这个类的实例对象.使用父类接受.可以向上转型.
3.匿名内部类.
上面所说的局部内部类.返回的时候是自己new了一个对象进行返回.且外面进行接受了. 我们还可以使用return的时候.字节返回.
就不用类定义了.
代码如下:
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():才可以.
代码如下.
public class AnmailB { public class AnmailC{ }
}
使用一个类继承AnmailC
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.成员变量; 这样使用的就是外部类的成员
Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字的更多相关文章
- Java开发知识之Java的数字处理类Math类
Java开发知识之Java的数字处理类Math类 一丶Java.text.DecimalFormat类与NumberFormat类 首先 Java.text.DecimalFormat指的是Decim ...
- Java开发知识之Java字符串类
Java开发知识之Java字符串类 一丶简介 任何语言中.字符串都是很重要的.都涉及到字符串的处理. 例如C++中. 字符串使用内存. 并提供相应的函数进行处理 strcmp strcat strcp ...
- Java开发知识之Java的枚举
Java开发知识之Java的枚举 一丶什么是枚举 枚举可以理解为就是常量,在Java中我们定义常量.都是用 final语句. C++中都是用const关键字. 枚举跟C++概念都是一样的.就是特定的常 ...
- Java开发知识之Java中的Map结构
Java开发知识之Java中的Map结构 一丶Map接口 Map没有实现Collection接口,提供的是Key 到Value的映射. Map中.不能包含相同的Key,每个Key只能映射一个Value ...
- Java开发知识之Java中的集合Set接口以及子类应用
---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...
- Java开发知识之Java中的集合上List接口以及子类讲解.
Java开发知识之Java中的集合类 一丶什么是集合类 如果你学习说数据结构,那么学习集合就很简单. 因为集合就是存储数据的结构. 例如 有链表结构 (list ) 还有 map结构.等等. 集合类就 ...
- Java开发知识之Java中的泛型
Java开发知识之Java中的泛型 一丶简介什么是泛型. 泛型就是指泛指任何数据类型. 就是把数据类型用泛型替代了. 这样是可以的. 二丶Java中的泛型 Java中,所有类的父类都是Object类. ...
- Java开发知识之Java的异常处理
Java开发知识之Java的异常处理 一丶异常概述 在讲解异常之前,我们要搞清楚.什么是异常. 通俗理解就是我们编写的程序出问题了.进行处理的一种手段. 比如我们的QQ.有的时候就崩溃了.比如出现xx ...
- Java开发知识之Java的继承多态跟接口*
Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...
随机推荐
- IOS8,IOS8.1等系统出现锁屏状态下WIFI断开问题的解决办法!
网络设备:TP-Link 300M无线路由器.DLINK 300M无线路由器.HP 300M无线路由器.APPLE AirPort无线路由器 终端:iphone5S+IOS8.1 故障现象:除appl ...
- TypeScript 函数-函数类型
//指定参数类型 function add(x:number,y:number){ console.log("x:"+x); // reutrn(x+y); } //指定函数类型 ...
- mpvue-docs基于vue来开发微信小程序
http://mpvue.com/和https://tencent.github.io/wepy/
- 读取 ini 配置文件
ini 配置文件格式:db_config.ini '''[section]option=value''' [DATABASE1] host=192.168.30.80 port= user=testa ...
- 批量引用iconfont字体图标到项目
打开https://www.iconfont.cn/网址登录后选择你需要的图标添加到购物车中 点击下载代码或者添加到项目后再下载代码,再找到之前下载的的文件,拷贝到项目中
- 梯度提升决策树(GBDT)
1.提升树 以决策树为基函数的提升方法称为提升树.决策树可以分为分类树和回归树.提升树模型可以表示为决策树的加法模型. 针对不同的问题的提升术算法的主要区别就是损失函数的不同,对于回归问题我们选用平方 ...
- live555工程建立与调试
Live555是一款开源的RTSP服务器,下载地址http://www.live555.com/liveMedia/public/ 下载下来的代码只有源文件,没有工程文件.那么如何使用VS 调试liv ...
- .NET程序员所需要注意的网站资源
一个程序员 需要 对 技术 和 行业 两方面同时具有极大热情和注意力才能让自己在一个新的台阶. 有些程序员是对技术有着极大的热情但是行业完全不注意,这样我感觉只能成为一个专家,并不能让自己真正的质变, ...
- 1.1 What is the plug-in?
A game center, such as Lianzhong in China, supports hundreds of games such as Chess, Bridges, ...
- Java提高篇(三):内部类和匿名内部类
一,内部类 其实内部类是十分简单的,我们根据其字里行间的意义就可以知道内部类应该是一个类当中的一个类,相当于一个类进行了嵌套,就如同循环的嵌套一般. 内部类有一个特征:内部类当中可以调用外部类当中的属 ...