`
zisefeiniao
  • 浏览: 168206 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

MLDN,第三天Java的面向对象之旅

阅读更多
今天所讲的知识点
A static关键字:六个用法分析
B 对象数组:定义和使用及内存分配图分析
C JDK 1.5对数组的新支持:foreach和可变参数
D 代码块:普通代码块、构造代码块、静态代码块
E 内部类




我对知识点的分析

A static关键字的用法一:
(1)当希望创建的所有对象共用一个属性的时候,可以把此属性设置为static属性;
(2)此时,此属性可以采用“类名.static属性名”直接使用;
(3)并且此属性值存放在全局数据区;
(4)在本类中访问此属性,可以不加“this.”修饰

static关键字的用法二:
(1)static除了可以修饰属性外,还可以修饰方法
(2)不过用static修饰的方法使用时有局限性,只能访问和调用同样用static修饰的属性和方法,不可调用非static的属性和方法
(3)不过非static的方法却可以访问和调用用static修饰的属性和方法,如果是本类中的不用加“this.”修饰,如果是非本类中的加上“类名.”修饰

static关键字的用法三:
(1)主方法main必须用static修饰
(2)如果希望在主类中定义的方法在main方法中能够直接调用,则定义的时候必须加上static修饰
(3)如果希望在主类中定义的方法在main方法中能够直接调用,但在定义的时候又不加static修饰,那么只能通过实例化一个匿名的主类对象来调用此方法,如:new 主类名().非static的方法名(参数);

static关键字的用法四:
(1)可以通过static定义静态代码块
(2)主类中的静态块优先于主方法执行,其他类中静态块在实例化对象的时候自动调用执行并且优先于构造块执行,不管有多少个对象产生,静态块只执行一次。

static关键字的用法五:
(1)用static修饰内部类
(2)使用static声明的内部类就成为外部类,这样在需要实例化内部类的时候就非常简单,格式为:
外部类.内部类名  对象名=new外部类.内部类名(参数列表);

static关键字的用法六:
(1)用加static修饰的属性来统计生成对象的个数;
例如:private static int Count=0;
方法是在无参构造方法中加Count++;
然后在其他构造方法中调用此构造方法:this();这样就可以通过Count属性知道产生对象的个数;
(2)还可以利用这点来完成某个对象名称的自动命名操作
例如:
class Book{
private String title ;
private static int count = 0 ; // 用于记录有多少个对象产生
public Book(){
  this.title = "title-" + count++ ;
}
public Book(String title){
  this.setTitle(title) ;
}
public void setTitle(String title){
  this.title = title ;
}
public String getTitle(){
  return this.title ;
}
public static int getCount(){
  return count ;
}
};

B 1、对象数组的定义格式:
类名称 对象数组名称[] = new 类名称[长度] ;
2、但是通过以上的定义语句只是声明了一个对象数组的名字,而每一个数组元素的值为null,例如:

每一个元素的名称又相当于每一个对象名,这个时候只是相当于声明了对象名一样,并没有对对象进行实例化,这个时候每个元素并没有具体的指向,所以都为null;
只有经过给每个元素实例化以后,采用使用每一个元素,也即每一个元素才有真正的指向;例如:

或者


C JDK 1.5对数组的新支持:foreach和可变参数
1、foreach是for的增强版,专门为遍历数组或集合中的值或对象而设置的。
语法:
for (类型 变量名称:数组或集合){
…..
}
说明:
(1)类型与数组或集合的类型一致,可以是基本数据类型也可以是引用数据类型;
(2)在循环过程中该变量依次代表数组或集合中的每一个元素;

2、可变参数
(1)在定义方法的时候可以不指定具体的参数个数,而是在调用的时候随意传入n个数据类型(0<=n<=任意个数);
(2)如果定义方法的时候有确定的参数和可变参数一起使用,那么可变参数必须放在最后一个参数位置;
(3)一组可变参数具有相同的数据类型;
(4)其实这组可变参数最终将以数组的形式接收;
(5)可变参数的数据类型可以是基本数据类型,也可以是引用数据类型;
例如:
public class Test3
{
public static void main(String args[]){
  print("aa",2,3,4,5);
}
public static void print(String str, int...y){
  System.out.println(str);
  for(int i:y){
   System.out.println(i);
  }
}
}

D 在程序中使用“{}”括起来的代码称为代码块。根据位置及声明的不同,代码块分为以下四种:
• 普通代码块
• 构造块
• 静态代码块
• 同步代码块,其中此代码块将在多线程部分进行讲解

1、普通代码块
在某个方法中单独用“{}”括起来的代码称为普通代码块。
主要作用是使得某些变量具有局部作用域;
例如:

注意:
(1)在普通代码块中定义的局部变量如果和在方法中直接定义的变量重名,那么普通代码块必须在其之前,否则会报错;
例如:
public class Test3{
public static void main(String args[]){
  int x = 100 ;
  System.out.println("x = " + x) ;
  { // 普通代码块
   int x = 10 ; // 局部变量
   System.out.println("x = " + x) ;
  }
}
};
报错信息:
已在 main(java.lang.String[]) 中定义 x
          int x = 10 ;    // 局部变量
              ^
(2)普通代码块所在方法被调用后,方法中的语句顺序执行,普通代码块中的语句不会优先被执行;

2、构造块
在某个类中,并且在方法外使用“{}”括起来的代码称为构造块。
注意:
(1)构造块总是优先于构造方法执行,不管两者的位置上下关系如何;
(2)而且每一个实例化对象产生时,都会自动调用构造块,会重复调用多次。
(3)定义构造块的位置为在某个类中,但在所有方法外,因为如果在某个方法内,就成了普通代码块了。
例如:
class Demo{
private int i;
public Demo(){
  System.out.println("构造方法。") ;
}
public Demo(int i){
  System.out.println("构造方法。"+i) ;
}
{ // 构造块
  System.out.println("构造块") ;
}
};
public class Test3{
public static void main(String args[]){
  new Demo() ;
  new Demo(2) ;
  new Demo() ;
}
};

3、静态块
在类中并且在方法外使用static声明的代码块称为静态代码块。
(1)定义静态块必须加static关键字,否则为构造块;
(2)定义静态块的位置必须是在类中,但在所有方法外,如果在方法内会报错;
例如:
public class Test3{
public static void main(String args[]){
  static{
   System.out.println("主方法中的静态块");
  }
}
};
报错信息:
非法的表达式开始
static{
^
(3)主类中的静态块优先于主方法执行,其他类中静态块在实例化对象的时候自动被执行,并且优先于构造块执行,不管有多少个对象产生,静态块只执行一次。
class Demo{
{ // 构造块
  System.out.println("构造块") ;
}
public Demo(){
  System.out.println("构造方法。") ;
}
static{ // 静态块
  System.out.println("静态代码块") ;
}
};
public class Test3{
public static void main(String args[]){
  System.out.println("-------------------------") ;
  new Demo() ;
  new Demo() ;
}
static{
  System.out.println("\n\n在主类中定义的静态块") ;
}
};
运行结果:
在主类中定义的静态块
-------------------------
静态代码块
构造块
构造方法。
构造块
构造方法。
构造块
构造方法。

E 1、内部类的概念
内部类即表示在一个类的定义中包含了另一个类的定义;
2、内部类的定义格式
(1)在类中定义内部类
缺点:①打破了常规类的定义格式(类中只有属性和方法);
②增加了外部类的负担;
优点:在内部类中可以直接访问外部类中的私有成员;
(2)在方法中定义内部类
同样,优点在于在内部类中可以直接访问外部类中的私有成员;
但是需要注意的一点:
在定义内部类的方法中需要带参数,或者需要定义变量,则必须带final修饰符;
例如:
class Outer{
private String info = "Hello World!!!" ;
public void fun(int temp){ // 方法中的参数
  String flag = "MLDN" ; // 方法中的变量
  class Inner{ // 在方法中定义内部类
   public void print(){
    System.out.println("temp = " + temp) ;
    System.out.println("flag = " + flag) ;
    System.out.println("info = " + info) ;
   }
  };
  new Inner().print() ;
}
};
public class Test3{
public static void main(String arg[]){
  new Outer().fun(30) ;
}
};
报错信息:
从内部类中访问局部变量 temp;需要被声明为最终类型
                 System.out.println("temp = " + temp) ;
                                                ^
从内部类中访问局部变量 flag;需要被声明为最终类型
                 System.out.println("flag = " + flag) ;
                                                ^
修改代码:
class Outer{
private String info = "Hello World!!!" ;
public void fun(final int temp){ // 方法中的参数
  final String flag = "MLDN" ; // 方法中的变量
  class Inner{ // 在方法中定义内部类
   public void print(){
    System.out.println("temp = " + temp) ;
    System.out.println("flag = " + flag) ;
    System.out.println("info = " + info) ;
   }
  };
  new Inner().print() ;
}
};
public class Test3{
public static void main(String arg[]){
  new Outer().fun(30) ;
}
};

3、实例化内部对象
(1)在外部要实例化内部类的对象,必须先实例化外部类对象,然后通过外部类的实例化对象去实例化内部类的对象;
例如:
class Outer{
private String info = "Hello World!!!" ;
class Inner{ // 内部类
  public void print(){
   System.out.println(info) ;
  }
};
};
public class InnerClassDemo03{
public static void main(String arg[]){
  Outer out = new Outer() ; // 产生外部类实例
  Outer.Inner in = null ; // 声明内部类对象
  in = out.new Inner() ;  // 实例化内部类对象
  in.print() ;
}
};
(2)如果想要在外部直接实例化内部类,而不通过外部类的实例化对象,则可以把内部类声明为static;

注意:
①使用static声明的内部类就成为外部类,可以不通过外部类的实例化对象直接实例化内部类的对象;
例如:
class Outer{
private static String info = "Hello World!!!" ;
static class Inner{ // 使用static声明内部类,成为外部类
  public void print(){
   System.out.println(info) ;
  }
};
};
public class InnerClassDemo06{
public static void main(String arg[]){
  Outer.Inner in = new Outer.Inner() ;  // 实例化内部类对象
  in.print() ;
}
};

②当把内部类声明为static类之后,在内部类中如果要直接访问外部类的属性和方法,则只能访问外部类中也标记为static的属性和方法,否则编译通不过;
例如:
class Outer{
private String info = "Hello World!!!" ;
static class Inner{ // 使用static声明内部类,成为外部类
  public void print(){
   System.out.println(info) ;
  }
};
};
public class Test3{
public static void main(String arg[]){
  Outer.Inner in = new Outer.Inner() ;  // 实例化内部类对象
  in.print() ;
}
};
报错信息:
无法从静态上下文中引用非静态 变量 info
         System.out.println(info) ;
                            ^
修改方法:
class Outer{
private static String info = "Hello World!!!" ;
static class Inner{ // 使用static声明内部类,成为外部类
  public void print(){
   System.out.println(info) ;
  }
};
};
public class Test3{
public static void main(String arg[]){
  Outer.Inner in = new Outer.Inner() ;  // 实例化内部类对象
  in.print() ;
}
};
③当内部类被声明为static之后,并不表示内部类中的非static方法自动转换成static级别的了,虽然其只能访问外部类中标记为static的属性和方法,他仍然可以访问内部类中的非static的属性和方法;
例如:
class Outer{
private static String info = "Hello World!!!" ;
static class Inner{ // 使用static声明内部类,成为外部类
  public void print(){
   System.out.println(info) ;
  }
};
};
public class Test3{
public static void main(String arg[]){
  Outer.Inner.print();
}
};
报错信息:
无法从静态上下文中引用非静态 方法 print()
Outer.Inner.print();
            ^
例如:
class Outer{
private static String info = "Hello World!!!" ;
static class Inner{ // 使用static声明内部类,成为外部类
  private int i=10;   //内部类中的非static的属性
  public void print(){
   System.out.println(info+i) ;   //可以访问内部类中的非static的属性
  }
};
};
public class Test3{
public static void main(String arg[]){
  Outer.Inner in = new Outer.Inner() ;  // 实例化内部类对象
  in.print() ;

}
};



项目案例:

A 1.使用运行时参数的形式完成一个简单的登陆程序:
例如:输入:java LoginDemo 用户名 密码
假设,用户名是abc,密码是123,如果正确则显示登陆成功,否则显示登陆失败。
本题目要求合理的考虑类的划分
个人收获:
学会了利用main()方法的参数利用

案例名称:

B 2、给出以下的操作代码,可以在Single类中增加任意的代码,只要可以在主方法处调用里面的打印方法即可。
class Single {
private Single(){}
public void print(){
  System.out.println("Hello World!!!") ;
}
};
public class SingleDemo{
public static void main(String args[]){}
};
个人收获:
体会了static关键字修饰方法的作用
案例名称:

C 使用Java的引用完成以下一种代码的开发
(NODE)-->(NODE)-->(NODE )
如果此种关系表示成功之后,现在就要求完成一个可以动态增加节点的操作类,此类可以完成以下功能:
(1)增加节点,在最后增加
(2)查找节点:判断指定的节点是否存在,节点中通过节点名称判断
(3)删除节点
(4)输出全部节点
提示:可以使用内部类方便的完成。
个人收获:
把以前学过的链表(结点)的数据结构知识利用了起来;
并且再次体会了内部类的特点和作用。


今天出现的问题


A class Demo
{
static{
  public static void Just1(){
   System.out.println("啊啊啊啊啊啊啊啊啊啊啊啊");
  }
}
{
  public static void Just2(){
   System.out.println("啊啊啊啊啊啊啊啊啊啊啊啊");
  }
}
public void print(){
  {
   public static void Just3(){
    System.out.println("啊啊啊啊啊啊啊啊啊啊啊啊");
  }
  }
}

}
解决方法:
得出结论:在普通代码块、构造块、静态块中都不能定义方法
在做题的时候发现,自己不能灵活的运用所学的知识。对于所讲的知识点基本能掌握,也似乎都理解,只是运用起来总感觉隔着一层膜,不是那么透彻,特别是this,内部类这几个地方,有些模糊。还需要加强代码的练习,培养感觉。
现在我把每天的日志编写当成了整理笔记和复习当天所学的知识,并且整理自己对知识点的理解和归纳总结。这样既可以对一天所学的知识有个整体的印象,也加深了记忆。
每天晚上睡觉之前,基本都会简单回忆一遍一天所学的新概念及应该注意的地方。
今天做作业第三题的时候,慢慢开始体会面向对象编程的特点和思路。虽然还不是恨透,不过有点感觉了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics