(原创) 脚踏实地学Java之:基础篇

     (原创)  脚踏实地学Java之:基础篇
 最近与几个朋友闲聊技术,当谈起他们各自用JAVA做项目时所用到的技术时,夸夸其谈,不知所云,犹如布什总统竞选前的演讲一般精彩,听的我是云里雾里,一头雾水!但当我问他们一些基础JAVA语言机制,与面向对象的一些基本思想时,回答起来却吞吞吐吐与刚才“演讲”时的表情却荡然不在!我就纳闷了“谈话前后时间不超过十分钟,这差距咋就这么大呢!!哈哈!!!”。
 好了,不闲扯了,谈正题吧。上边说了这么多,意思就是,学习就要跟做人做事一样,脚踏实地,一步一个脚印,在学习技术的路上容不得半点虚假,也没有所谓的捷径可走,如果你走了弯路,相信你总有一天还是再要走会来的。这就是我写这篇文章的目的,帮助那些正在学习或用JAVA做开发的人员掌握技术细节,打好基础。
 注:本系列前几篇文章使用实例来讲解一些基础概念,以后的章节里会不断对JAVA机制深入。如果您是工作了几年的高手就帮我挑挑错,不胜感激!!!如果您是初学JAVA者,我建议你把我做的实例用你的理解重现一便,如果有技术问题可以共同探讨。我的邮箱地址:billzhangmingmging@sina.com.cn

(1) equals 与 == 的比较 (公认为在java界面试时最常问到的问题):
 primitive类型存储在栈中,它不是对象类型,所以primitive 类型中也就不可能包含equals方法。对于基本类型,没有向对象中发送消息的说法,自然也不会有方法成员的存在。

1)    使用 “==”来比较两个基本(primitive)类型值是否相等:

/*----------------------------------------------------------------------------------------------*/
public class TestEquals
{
 public static void main(String[] args)
 {
  int i = 5,j = 3;
  System.out.println ( i == j ? "the object equals !!":
  "the object unequals!!!!!!!!!!!!");
 }
}

/*----------------------------------------------------------------------------------------------*/
RESULT:
the object unequals!!!!!!!!!!!!
相反,如果两个变量的值相等,则输出为the object equals !!

2)    使用“==”来比较两个对象引用是否相等:

/*----------------------------------------------------------------------------------------------*/
class Cup
{}
public class ObjectCompare
{
 public static void main(String[] args)
 {
  Cup cup1 = new Cup();
  Cup cup2 = new Cup();
  System.out.println (cup1 == cup2 ? "The object reference equals" :
  "The object reference unequals");
 }
}

/*----------------------------------------------------------------------------------------------*/
RESULT :
The object reference unequals

3)    使用equals方法(java 中所有对象共有方法)来比较两个对象(逻辑上)是否一致:

/*----------------------------------------------------------------------------------------------*/
class a
{
 int i = 5;
 public boolean equals(final Object object)
 {
  return (((b)object).i==i);
 }
}
class b
{
 int i = 5;
 public boolean equals(final Object object)
 {
  return(((a)object).i==i);
 }
}
public class TestEqua
{
 public static void main(String args[])
 {
  a a = new a();
  b b = new b();
  System.out.println ( b.equals(a) ? "equals!!!!!!!!!!" : "unequals");
 }
}
/*----------------------------------------------------------------------------------------------*/

RESULT :
equals!!!!!!!!!!
这两个对象相等的方法是自定义的(只要两个对象中的变量i的值相等,则它们就是相等的),就是说,相等的条件是由用户根据具体的业务需求来定义的。

(2)接口与继承类:

 接口(interface): 接口定义了实现它的子类的类型形式,其中包括方法的名称、方法的返回值、参数列表,JAVA不支持多重继承,要实现象C++中类多重继承的功能,就用到了接口(因为你可以实现多个接口,接口又同时可以继承接口,当然了,还有别的方法实现多重继承,在以后的文章会逐一介绍)。曾有这样的说法,面向对象的编程就是面向接口的编程,这句话足以说明接口在面向对象的概念里的重要位置,关于interface的更深入内容我会在今后的文章里详细讲解,,在这里只是用到了接口的概念所以进行了简单介绍。

 继承(extends): 如果一个类从另一个继承,你就可以说:这个类就是被继承的那个类,通常被继承的类叫做超类(superClas),而继承类叫做子类(subClass),与此同时子类可以拓展与覆写超类的方法与属性。
 
类TestInterOrExtends 实现了接口b与抽象类a,接口与抽象类里都定义了event方法,在TestInterOrExtends 里不会冲突。

/*----------------------------------------------------------------------------------------------*/
abstract class A
{
 public void event()
 {
  System.out.println ("The abstract class event method!!!!!!!!!!!!!!");
 }
}
interface B
{
 public void event();
}
public class TestInterOrExtends extends A implements B
{
 public void event()
 {
  System.out.println ("The event of extend!!!!!!!!!!!!!!!!!!");
 }
 public static void main(String agrs[])
 {
  new TestInterOrExtends().event();
 }
}
/*----------------------------------------------------------------------------------------------*/
The result : The event of extend!!!!!!!!!!!!!!!!!!

(3)类的调用顺序:
子类总是优先调用父类默认的构造函数,调用的顺序也就是按照继承的顺序线形排列。

/*----------------------------------------------------------------------------------------------*/
class A
{
 public A()
 {
  System.out.println ("The Constructor of a ");
 }
}
public class TestInterOrExtends extends A
{

 public TestInterOrExtends()
 {
  System.out.println ("The Constructor of TestInterOrExtends");
 }
 public static void main(String agrs[])
 {
  new TestInterOrExtends();
 }
}
/*----------------------------------------------------------------------------------------------*/
The result :  The Constructor of a
  The Constructor of TestInterOrExtends
  
  
关于调用顺序的说明,前几天在论坛上看见一个经典的例子与大家共享:
/*----------------------------------------------------------------------------------------------*/
public class Test2 extends Test1{
 {
  System.out.print("1");
 }
 Test2(){
  System.out.print("2");
 }
 static{
  System.out.print("3");
 }
 {
  System.out.print("4");
 }
 public static void main(String[] args) {
  new Test2();
 }
}
class Test1 {
 Test1(){
  System.out.print("5"); 
 }
 static{
  System.out.print("6");
 }
}
/*----------------------------------------------------------------------------------------------*/
RESULT :
635142

 

(4)接口里的成员必须全部是public的,如果不写public则默认是public的,如过将接口内的成员函数或方法声明为private or protected的
则编译器将会在编译时产生错误,如果在接口里声明了变量,则它们就是static 和 final的。

/*----------------------------------------------------------------------------------------------*/
interface aaa
{
 protected void a();
 public void b();
}
class bb implements aaa
{
 public void a()
 {
  System.out.println ("The implemention aaa of bb");
 }
 public void b()
 {
  System.out.println ("The implemention aaa of bb's method");
 }
}
public class TestMyInter
{
 public static void main(String[] args)
 {
  aaa a = new bb();
  a.a();
 }
}
/*----------------------------------------------------------------------------------------------*/
result :
--------------------Configuration: JDK version <Default>--------------------
F:/homeWork/JAVA/TestMyInter.java:3: modifier protected not allowed here
 protected void a();
                       ^
1 error


<5> 类型转换:
下传(downCasting)是不安全的如 :
/*----------------------------------------------------------------------------------------------*/
class a
{
 public void mm()
 {
  System.out.println ("MMZHANG");
 }
}
class b extends a
{
}
public class DownCasting
{
 public static void main(String[] args)
 {
  try
  {
  b b = new b();
  a a = new a();
  ((b)a).mm();
  }
  catch(Exception ex)
  {
   ex.printStackTrace();
  }
 
 }
}
/*----------------------------------------------------------------------------------------------*/

这种将父类转换为子类可以通过编译,但会在run time 时产生异常:
Run time Result :
java.lang.ClassCastException
        at DownCasting.main(DownCasting.java:19)
如果将类的转换变为上传(upCasting)则是安全的,因为父类具有子类的所有属性方法,而子类不仅包含了父类的方法属性而且具有自身拓展的属性及方法,而拓展的这些方法在父类里并没有体现。所以,上传是安全的。

<6>  Class.forName(String); 使用类名字符串作为参数,返回Class的Reference,但事实上在程序里并没有用到这个Reference.
 Note : Must be caught exception
/*----------------------------------------------------------------------------------------------*/
class aa
{
 static
 {
  System.out.println ("The static method aa");
 }
 
}
class bb
{
}
public class ClassForName
{
 public static void main(String[] args)
 {
  try
  {
   Class.forName("aa");
  }
  catch(ClassNotFoundException ex)
  {
   System.out.println ("The class not found ");
  }
 }
}
/*----------------------------------------------------------------------------------------------*/

<7> Java编程语言只由值传递参数!!!C++转Java的程序员容易对这一点混淆(C++有引用类型)。
    当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用(就是说,当你向一个方法传递参数时,传递给方法的参数就是该对象引用的副本)。
For example :
/*----------------------------------------------------------------------------------------------*/

public class TestPara
{
 public static void main(String[] args)
 {
  String str = "zhangmingming";
  System.out.println ("The derive string object is :" + str); // Define a string object
  TestPara.changeParameter(str);
  System.out.println("The string object value is :" + str);
 }
 public static void changeParameter(String parameter )
 {
  parameter = "billzhangmingming";
  System.out.println ("The changed parameter is :" +parameter);
 }
}
/*----------------------------------------------------------------------------------------------*/

The derive string object is :zhangmingming
The changed parameter is :billzhangmingming
The string object value is :zhangmingming
Press any key to continue...
在 changeParameter方法里,将传递进来的对象的reference改变了,这使得对象reference的拷贝引用指向了别的对象,所以它并没有对传入的对象值做任何改变。

<8> Super 关键字:指自身对象的父类。它可以:
 (1) 调用父类构造函数
 (2)调用父类成员或方法
    使用格式: super.member(member可以是函数或方法)

For example:
/*----------------------------------------------------------------------------------------------*/
class SuperClass
{
 String name = "zmm";
 SuperClass()
 {
  System.out.println ("Call super class default construct!!!!!!!");
 }
 SuperClass(int a)
 {
  System.out.println ("Call super class that has one of parameter construct!!!!!!!!!!");
 }

}
class ExtendsSuperClass extends SuperClass
{
 String name = "Bill";
 ExtendsSuperClass()
 {
  super();  //No problem
  System.out.println ("The child class construct ");
//  super();  // call to super must be first statement in constructor.
 }
 ExtendsSuperClass(int a)
 {
  super(a);
 }
 void chanageName(String superName,String subClassName)
 {
  super.name = "zhangmingming";   //Invoke super class atrribue and change it.
  this.name = "billzhangmingming";
 }
 void showMyName()
 {
  System.out.println ("The superClass name is :" + super.name);
  System.out.println ("The subClass name is :" + this.name);
 }
 
}
public class TestSuper
{
 public static void main(String[] args)
 {
  ExtendsSuperClass test;
  test = new ExtendsSuperClass();
  int a = 10;
  test = new ExtendsSuperClass(a);
  test.showMyName();
  
 }
}
/*----------------------------------------------------------------------------------------------*/
NOTICE:
(1)如果Super关键字写在了ExtendsSuperClass 默认构造函数打印语句之后程序则会在编译时产生如下错误:
F:/homeWork/JAVA/TestSuper.java:17: call to super must be first statement in constructor
  super();
                     ^
1 error
(2)子类以隐藏(覆写)了父类name属性,但使用Super便可轻松的访问父类的属性,并没有被子类的覆写所影响。
RESULT :
Call super class default construct!!!!!!!
The child class construct
Call super class that has one of parameter construct!!!!!!!!!!
The superClass name is :zmm
The subClass name is :Bill
Press any key to continue...

<9> Static 简介 :
静态成员不必依靠类的对象来访问,如果类中的成员被声明为Static,则该成员(属性或方法)就可以在类创建对象之前被访问,Static方
法的经典例子就是main方法,因为在程序开始执行时必须首先调用main(),所以它被声明为Static。
静态函数与变量可以使用类名称直接调用,这是由于static成员并不依靠任何类对象特征的体现。
如:ClassName.StaticMember (这个特性,不禁让我让我想起了“大史记”中的那句经典对白:“我不是你二叔,我是玉帝派来的神仙,只不过是借用你二叔的肉身而已!!!”)
也可以使用静态成员所在类的对象名来访问 如:Obj.StaticMember。
可以将声明为static的变量看作是全局变量,如果一个类中包含有static变量,则在声明一个对象时,并没有产生static变量的拷贝,
如果类中的方法需要使用自己类里被声明为static变量则有两种访问方式:
 1)将方法声明为static。
 2)使用本类的类名来调用。也就是上面提到的ClassName.StaticMember。
 3)如果需要将static变量当参数传给一个方法,则该方法必须被声明为static(这是初学Java在编程时常犯的错误之一)。

EXAMPLE:
/*----------------------------------------------------------------------------------------------*/
public class TestStatic
{
 static int i = 10;
 public static void main(String args[])
 {
  StaticClassMember a = new StaticClassMember();
  a.method1();  // Call static member used object name.
  System.out.println ("The static property value is :" + TestStatic.i);
  i = i + 5;    
  System.out.println ("The static property value is :" + TestStatic.i); 
  aaa(i);    // Passing static member.It's little funny.    

 }
 static void aaa( int a)
 {}
}

class StaticClassMember
{
 
 static void method1()
 {
  System.out.println ("The static method1");
 }
}

/*----------------------------------------------------------------------------------------------*/

The static method1
The static property value is :
The static property value is :

NOTE :  无论你创建了多个TestStatic,它们都会使用同样的i变量,因为所有的对象都引用了同样的内存地址。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值