上季内容回顾:
题目的分析和类图的设计
本季主要知识点:
本季要点:内部类的定义、使用和外部调用。
本季重点讲解了JAVA中的内部类和对象数组的使用,以及对上季中的习题进一步引申。
上季内容遗留下来这么一道题目,我们来分析一下哈~
class Employee
{
private String empno ;
private String empname ;
private float salary ;
private float inc ;
//构造方法
public Employee(){}
public Employee(String empno,String empname, float salary, float inc){
this.setEmpno(empno);
this.setEmpname(empname);
this.setSalary(salary);
this.setInc(inc);
}
//setter和getter
public void setEmpno(String empno){
this.empno = empno ;
}
public void setEmpname(String empname){
this.empname = empname ;
}
public void setSalary( float salary){
this.salary = salary ;
}
public void setInc( float inc){
this.inc = inc ;
}
public String getEmpno(){
return this.empno ;
}
public String getEmpname(){
return this.empname ;
}
public float getSalary(){
return this.salary ;
}
public float getInc(){
return this.inc ;
}
//计算增长后的工资总额
public float calSalary(){
return this.salary+ this.salary* this.inc;
}
}
public class Demo01
{
public static void main(String args[]){
Employee e = new Employee( "e001", "王乾",5000.0f,0.1f);
System.out.println(e.calSalary());
}
}
{
private String empno ;
private String empname ;
private float salary ;
private float inc ;
//构造方法
public Employee(){}
public Employee(String empno,String empname, float salary, float inc){
this.setEmpno(empno);
this.setEmpname(empname);
this.setSalary(salary);
this.setInc(inc);
}
//setter和getter
public void setEmpno(String empno){
this.empno = empno ;
}
public void setEmpname(String empname){
this.empname = empname ;
}
public void setSalary( float salary){
this.salary = salary ;
}
public void setInc( float inc){
this.inc = inc ;
}
public String getEmpno(){
return this.empno ;
}
public String getEmpname(){
return this.empname ;
}
public float getSalary(){
return this.salary ;
}
public float getInc(){
return this.inc ;
}
//计算增长后的工资总额
public float calSalary(){
return this.salary+ this.salary* this.inc;
}
}
public class Demo01
{
public static void main(String args[]){
Employee e = new Employee( "e001", "王乾",5000.0f,0.1f);
System.out.println(e.calSalary());
}
}
测试下哈~
class Math
{
private float x;
private float y;
public Math(){}
public Math( float x, float y){
this.setX(x);
this.setY(y);
}
//求和
public float sum(){
return this.x + this.y;
}
//求差
public float sub(){
return this.x - this.y;
}
//求平均值
public float avg(){
return this.sum() / 2;
}
//求最大值
public float max(){
return this.x> this.y? this.x: this.y;
}
//求最小值
public float min(){
return this.x< this.y? this.x: this.y;
}
public void setX( float x){
this.x = x;
}
public void setY( float y){
this.y = y;
}
public float getx(){
return this.x;
}
public float gety(){
return this.y;
}
}
public class Demo02
{
public static void main(String args[]){
Math m = new Math(50.0f,60.0f);
System.out.println( "求和:"+m.sum());
System.out.println( "求差:"+m.sub());
System.out.println( "平均值:"+m.avg());
System.out.println( "最大值:"+m.max());
System.out.println( "最小值:"+m.min());
}
}
{
private float x;
private float y;
public Math(){}
public Math( float x, float y){
this.setX(x);
this.setY(y);
}
//求和
public float sum(){
return this.x + this.y;
}
//求差
public float sub(){
return this.x - this.y;
}
//求平均值
public float avg(){
return this.sum() / 2;
}
//求最大值
public float max(){
return this.x> this.y? this.x: this.y;
}
//求最小值
public float min(){
return this.x< this.y? this.x: this.y;
}
public void setX( float x){
this.x = x;
}
public void setY( float y){
this.y = y;
}
public float getx(){
return this.x;
}
public float gety(){
return this.y;
}
}
public class Demo02
{
public static void main(String args[]){
Math m = new Math(50.0f,60.0f);
System.out.println( "求和:"+m.sum());
System.out.println( "求差:"+m.sub());
System.out.println( "平均值:"+m.avg());
System.out.println( "最大值:"+m.max());
System.out.println( "最小值:"+m.min());
}
}
我们验证下计算结果对不对哈~
内部类
本次专题中JAVA SE 课程已经融合了JAVA EE的设计思路
在一个类的内部还有另外一个类
class Outer{
定义了若干个属性
定义了若干个方法
class Inner{
// 内部类
}
}
定义了若干个属性
定义了若干个方法
class Inner{
// 内部类
}
}
内部类定义后有什么好处呢?我们来看Demo03哈~
//外部类
class Outer
{
private String name = "redking.blog.51cto.com" ;
//内部类
class Inner
{
//此方法用于打印Outer类中的name属性
public void printName(){
System.out.println( "name = "+name) ;
}
}
//定义一个外部类的方法
public void fun(){
//产生内部类的实例化对象,同时调用里面的方法
new Inner().printName() ;
}
}
public class Demo03
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//调用fun()方法之后打印输出
out.fun() ;
}
}
class Outer
{
private String name = "redking.blog.51cto.com" ;
//内部类
class Inner
{
//此方法用于打印Outer类中的name属性
public void printName(){
System.out.println( "name = "+name) ;
}
}
//定义一个外部类的方法
public void fun(){
//产生内部类的实例化对象,同时调用里面的方法
new Inner().printName() ;
}
}
public class Demo03
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//调用fun()方法之后打印输出
out.fun() ;
}
}
验证下效果
编译*.java文件之后,可以发现产生了两个文件:
· Outer$Inner.class : Outer.Inner,如果要想找到Inner类,则必须先找到Outer
· Outer.class :外部类的class文件。
· Outer$Inner.class : Outer.Inner,如果要想找到Inner类,则必须先找到Outer
· Outer.class :外部类的class文件。
能否发现内部类有哪些好处呢?
现在将内部类拿到外部类之外,要求;最后可以实现同样的程序,我们来看Demo04哈~
现在将内部类拿到外部类之外,要求;最后可以实现同样的程序,我们来看Demo04哈~
//外部类
class Outer
{
private String name = "redking.blog.51cto.com" ;
//定义一个外部类的方法
public void fun(){
//产生内部类的实例化对象,同时调用里面的方法
new Inner( this).printName() ;
}
//必须使用setter和getter方法
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
//现在我们把内部类拿到外部,这样就形成了两个类哈~
//内部类
class Inner
{
//必须想办法为out对象实例化
private Outer out = null ;
public Inner(Outer out){
this.out = out ;
}
//此方法用于打印Outer类中的name属性
public void printName(){
//此处如果要访问name属性,则肯定必须通过Outer类的对象来完成
System.out.println( "name = "+out.getName()) ;
}
}
public class Demo04
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//调用fun()方法之后打印输出
out.fun() ;
}
}
class Outer
{
private String name = "redking.blog.51cto.com" ;
//定义一个外部类的方法
public void fun(){
//产生内部类的实例化对象,同时调用里面的方法
new Inner( this).printName() ;
}
//必须使用setter和getter方法
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
//现在我们把内部类拿到外部,这样就形成了两个类哈~
//内部类
class Inner
{
//必须想办法为out对象实例化
private Outer out = null ;
public Inner(Outer out){
this.out = out ;
}
//此方法用于打印Outer类中的name属性
public void printName(){
//此处如果要访问name属性,则肯定必须通过Outer类的对象来完成
System.out.println( "name = "+out.getName()) ;
}
}
public class Demo04
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//调用fun()方法之后打印输出
out.fun() ;
}
}
修改完后我们看下效果
以上程序多了很多内容:
1、 Outer.class类中多了setter和getter方法,同时在fun方法中还必须传入当前操作Outer类的对象,因为Inner类中必须使用此对象才可以访问Outer类中的属性。
2、 Inner.class 类中多了一个构造方法,用于接收Outer 类的实例化对象,同时必须使用对象.方法()的形式才可以找到name的值并输出。
1、 Outer.class类中多了setter和getter方法,同时在fun方法中还必须传入当前操作Outer类的对象,因为Inner类中必须使用此对象才可以访问Outer类中的属性。
2、 Inner.class 类中多了一个构造方法,用于接收Outer 类的实例化对象,同时必须使用对象.方法()的形式才可以找到name的值并输出。
综合以上几点,发现内部类的优缺点
· 内部类访问外部类的私有属性很方便
· 内部类在使用时代码的结构是不好的
· 内部类访问外部类的私有属性很方便
· 内部类在使用时代码的结构是不好的
下面我们还是看Demo03,在此基础上我们不想使用fun()方法调用printName()方法,希望直接在主方法中调用,我们看下面。
//外部类
class Outer
{
private String name = "redking.blog.51cto.com" ;
//内部类
class Inner
{
//此方法用于打印Outer类中的name属性
public void printName(){
System.out.println( "name = "+name) ;
}
}
}
public class Demo05
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//能否直接在Main方法中直接产生Inner类的实例化对象
//调用printName方法呢?我们验证一下哈~~~
//声明内部类对象:外部类.内部类 内部类对象 = null ;
//实例化内部类对象:内部类对象 = new 外部类实例.new 内部类() :
Outer.Inner in = out.new Inner() ;
in.printName() ;
}
}
class Outer
{
private String name = "redking.blog.51cto.com" ;
//内部类
class Inner
{
//此方法用于打印Outer类中的name属性
public void printName(){
System.out.println( "name = "+name) ;
}
}
}
public class Demo05
{
public static void main(String args[]){
//产生了外部类的对象
Outer out = new Outer() ;
//能否直接在Main方法中直接产生Inner类的实例化对象
//调用printName方法呢?我们验证一下哈~~~
//声明内部类对象:外部类.内部类 内部类对象 = null ;
//实例化内部类对象:内部类对象 = new 外部类实例.new 内部类() :
Outer.Inner in = out.new Inner() ;
in.printName() ;
}
}
测试下,可以哈,这是这样代码就更加别扭了哈~
此外,也可以在一个方法中定义内部类。
class Outer
{
private String name = "redking.blog.51cto.com" ;
public void fun(){
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
}
}
new Inner().print();
}
}
public class Demo06
{
public static void main(String args[]){
new Outer().fun();
}
}
{
private String name = "redking.blog.51cto.com" ;
public void fun(){
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
}
}
new Inner().print();
}
}
public class Demo06
{
public static void main(String args[]){
new Outer().fun();
}
}
验证下
注意点:
在方法中定义的内部类,可以访问外部类的任何属性,但是不能直接访问方法中的参数或变量。
在方法中定义的内部类,可以访问外部类的任何属性,但是不能直接访问方法中的参数或变量。
这么理解呢?我们来看下Demo07哈~
class Outer
{
private String name = "redking.blog.51cto.com" ;
public void fun( int i){
int j = 10 ;
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
System.out.println( "i+j = "+(i+j));
}
}
new Inner().print();
}
}
public class Demo07
{
public static void main(String args[]){
new Outer().fun(20);
}
}
{
private String name = "redking.blog.51cto.com" ;
public void fun( int i){
int j = 10 ;
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
System.out.println( "i+j = "+(i+j));
}
}
new Inner().print();
}
}
public class Demo07
{
public static void main(String args[]){
new Outer().fun(20);
}
}
就像这样哈:
如果想在内部类中访问方法中的参数,则参数前必须加上一个“final”关键字。
class Outer
{
private String name = "redking.blog.51cto.com" ;
public void fun( final int i){
final int j = 10 ;
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
System.out.println( "i+j = "+(i+j));
}
}
new Inner().print();
}
}
public class Demo08
{
public static void main(String args[]){
new Outer().fun(20);
}
}
{
private String name = "redking.blog.51cto.com" ;
public void fun( final int i){
final int j = 10 ;
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println( "name = "+name);
System.out.println( "i+j = "+(i+j));
}
}
new Inner().print();
}
}
public class Demo08
{
public static void main(String args[]){
new Outer().fun(20);
}
}
现在程序就执行了
对象数组:
· 数组:是一组相同类型变量的集合
· 对象数组:就是一组对象。
· 数组:是一组相同类型变量的集合
· 对象数组:就是一组对象。
对象数组的定义格式:
声明对象数组:类名称 [] 对象数组名称 = null ;
为对象数组开辟空间:对象数组名称 = new 类名称[个数] ;
声明对象数组:类名称 [] 对象数组名称 = null ;
为对象数组开辟空间:对象数组名称 = new 类名称[个数] ;
注意:
数组中使用new开辟空间之后,所有的数据都是默认值,对象的默认值就是null。
数组中使用new开辟空间之后,所有的数据都是默认值,对象的默认值就是null。
class Person
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo09
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i]);
}
}
};
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo09
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i]);
}
}
};
我们看下效果,现在所有的对象的默认值都是null
现在我们分别为对象数组中的每个元素实例化
class Person
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo10
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//因为使用的是动态初始化
//所以此处必须依次为其实例化,对象数组中的每一个元素都是null
for ( int i=0;i<p.length ;i++ )
{
//分别为对象数组中的每个元素实例化
p[i] = new Person( "michael"+i,20+i);
}
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i]);
}
}
};
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo10
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//因为使用的是动态初始化
//所以此处必须依次为其实例化,对象数组中的每一个元素都是null
for ( int i=0;i<p.length ;i++ )
{
//分别为对象数组中的每个元素实例化
p[i] = new Person( "michael"+i,20+i);
}
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i]);
}
}
};
我们看下对象数组中有没内容了
对象数组中每个元素都有内容了,下面我们就来取出内容哈~
class Person
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo11
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//因为使用的是动态初始化
//所以此处必须依次为其实例化,对象数组中的每一个元素都是null
for ( int i=0;i<p.length ;i++ )
{
//分别为对象数组中的每个元素实例化
p[i] = new Person( "michael"+i,20+i);
}
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i].getInfo());
}
}
};
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo11
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = null ;
//为对象数组开辟空间
p = new Person[10] ;
//因为使用的是动态初始化
//所以此处必须依次为其实例化,对象数组中的每一个元素都是null
for ( int i=0;i<p.length ;i++ )
{
//分别为对象数组中的每个元素实例化
p[i] = new Person( "michael"+i,20+i);
}
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i].getInfo());
}
}
};
验证下
这就叫对象数组哈~
对象数组也可以采用静态初始化方式:
class Person
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo12
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = { new Person( "michael",30), new Person( "amy",31), new Person( "joy",32)} ;
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i].getInfo());
}
}
};
{
private String name ;
private int age ;
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
//所有的信息不能直接在类中输出,必须返回
public String getInfo(){
return "姓名:"+ this.name+ ",年龄:"+ this.age;
}
};
public class Demo12
{
public static void main(String arg[]){
//声明一个Person类的对象数组
Person p[] = { new Person( "michael",30), new Person( "amy",31), new Person( "joy",32)} ;
//开辟空间之后所有的内容都是默认值,引用的为null
for ( int i=0;i<p.length ;i++ )
{
System.out.println(p[i].getInfo());
}
}
};
看下效果哈~
思考题:
建立一个Student 类,里面包含name、age、score 属性,现在要求生成十个Student 对象,之后对这些对象进行排序,按成绩由高到低排序,如果成绩相等,则按年龄由高到低排序。
建立一个Student 类,里面包含name、age、score 属性,现在要求生成十个Student 对象,之后对这些对象进行排序,按成绩由高到低排序,如果成绩相等,则按年龄由高到低排序。
总结
1、内部类的使用
· 内部类的优点与缺点
2、对象数组,是一组对象,必须分别实例化
3、思考题非常重要哈~~~(留到面向对象结束后分析哈)
###############################################################
本文转自redking51CTO博客,原文链接:
http://blog.51cto.com/redking/124073
,如需转载请自行联系原作者
