发新话题
打印

JAVA学堂_____从零开始

第十七课  面向对象的基本概念(2)

一、对象的使用:
通常我们访问的格式如下:
<对象名>.<变量名>
<对象名>.<方法名>
比如说上面的例子中
public class Car{
int gearNum;
int engine;
public Car(){}
public void Equipment(int g,float e){
  this.gearNum=g;
  this.engine=e;
}
}
然后我们实例化一个对象
Car Test=new Car();
那么我们在访问该汽车的排档数和排气量的时候可以:
Test.gearNum=4;
Test.engine=1000;
当然我们也可以通过调用方法来改变设置:
Test.Equipment(5,2000);
当然我们也可以在生成对象的时候直接引用方法:
Car Test1=new Car().Equipment(4,1000);
注:我们在这里暂不讨论对象的释放问题,因为JAVA中有“垃圾回收”的机制,它每隔20ms进行自动回收一次

二、类:在JAVA中类是基本要素,所有的对象都是由类产生的,下面我们说一下常见的存取修饰符:
public        可用于类、变量、方法,表示它可被任何类的成员存取(公有)
protected        可用于变量和方法,表示它可以被该类的子类或位于同一个包的类成员存取
private        可用于变量和方法,它表示只能被位于同一个类的成员存取(私有)
(friendly)        默认修饰符,表示它只能被位于同一个包的类成员存取
final        可用于类、变量和方法,若用于类,则代表该类没有子类;若用于变量,一
        旦该变量设置后,就不再改变;若用于方法,代表该方法无法被替代(常量)
abstract        可用于类及方法,此类必须为某类的父类,无法直接使用
static        可用于变量和方法,表示它可以为类的所有对象共享(静态)
native        只用于方法,可以使用程序无法跨平台
transient        仅用于变量,表示该变量不会在serialization的过程中写出(暂时)
synchronized        仅用于方法,在多线程中用于重要程序段的存取
volatile        仅用于变量,表示该变量可以被多个线程所改变,提示编译器不应该将该
        变量优化,这可以避免读不到正确的值(共享)
三、类的基本结构:
[修饰符]  class 类名  [extends 父类名] [implements 类实现的接口列表]
{
成员变量声明
成员方法声明
}
说明:
1、成员变量必须放在类体中,但不能放在某个方法中
2、类的属性一般说明3个方面的内容:父类、此类提供的接口、类的特性
3、extends用来说明它的父类

TOP

第十八课  面向对象的基本概念(3)

类的成员变量:我们在定义类的成员变量时,包括两个部分,其中第一部分是类型说明,第二个部分是成员名。在定义类型的时候我们要考虑以下三个方面
①变量的访问权限
②是否为静态变量
③是否为常量
一、静态变量:分为成员变量和非成员变量,如:
class A{
int a;
void B(){
  int b;
  }
}
在这里面 a为成员变量,而b则为非成员变量
又如:
class A{
static String a;
String b;
}
这里面我们称a为类变量,那么a 和b 的区别是,当同时赋给两个不同的对象时,a只占一个存储空间,而 b则占两个存储空间
我们来看这样一个例子:
import java.lang.Math;
public class StaticTest{
static double Pi=Math.PI;
static double E=Math.E;
static double A=149.6/100;
static double Mercury,Venus,Earth;
static{
Mercury=0.387099*A;
Venus=0.723332*A;
Earth=A;
}
public static void StaticTest(){
System.out.println("\nPI="+Pi+"\nE="+E);
System.out.println("行星与太阳的距离为:");
System.out.println("水星"+Mercury+"\n金星"+Venus+"\n地球="+Earth);
}
public static void main(String args[]){
StaticTest s=new StaticTest();
double s1=Math.PI+Math.E;
s.StaticTest();
  System.out.println("\nEarth="+s.Earth);
}
}
说明:
1、静态方法只能被其它静态方法调用
2、其子类不能有同名同参数的方法
3、静态变量是全局变量,可以在任何地方调用
4、要成批初始化静态变量,可用静态块
二、常量:一但定义无法修改
我们来看一个错误的例子:
public class FinalTest{
public static void main(String args[])
{
final int a=10;
a=20;
System.out.println(a);
}
}

TOP

第十八课  面向对象的基本概念(4)
一、类的方法:实际上,类的方法就是实现某一功能的程序块
格式:
[修饰符] 返回值类型 方法名([参数]) [throws 例外名……]
{
  局部变量名;
  执行语句组;
}
定义:
public void aa1(int i1,int i2)
{
  //程序代码;
  return;
}
调用:
public class Mymethod
{
public static void aa1(int i1,int i2)
{
    //程序代码;
   return;
}
public static void main(String args[])
{
  int index1=0;
  int index2=1;
  //程序代码
  aa1(index1,index2);
  //程序代码
}
}
下面我们举一个实例说明一下
public class Test{
        public static void div(int i1,int i2)
        {
                System.out.println(i1+"/"+i2+"="+i1/i2);
                return;
        }
        public static void main(String args[]){
                int index1=6,index2=3;
                div(index1,index2);
                System.out.println("控制权回到main方法中");
        }
}
二、说明:
1、修饰符:
  static:静态方法,不需实例化就可访问
以下两种情况可能用到静态方法:
①当一个方法不需要访问对象的状态时
②当一个方法只需要访问类中的静态方法时
  final:表明是最终方法,不能被覆盖。如果一个类中的所有变量和方法都是最终的,那么此类为最终类,不能被继承。
2、返回值类型:
如果没有返回值时,则为void
3、方法名:建议第一个字母为小写,其余的每个单词的每一个字母为大写
4、参数传递:
①传递实际的值:实际参数必须是简单变量或常数
public class SumCal{
public static void main(String args[])
{
int j=10;
System.out.println("main in j is :"+j);
calculate(j);
System.out.println("at last main in j is"+j);
}
static void calculate(int j){
for (int i=0;i<10;i++)
j++;
System.out.println("method in j is:"+j);
}
}
②传递地址:通常我们可以用数组做为实际参数
public class SendAdress{
        public static void main(String args[]){
                int aa[]=new int[5];
                System.out.println("before entering method:");
                for(int i=0;i<5;i++)
                System.out.println("aa["+i+"]="+aa);
                test(aa);
                System.out.println("after method:");
                for(int i=0;i<5;i++)
                  System.out.println("aa["+i+"]="+aa);
                }
        static void test(int x[])
        {
                System.out.println("int method:");
                for (int i=10;i<15;i++)
                 {x[i-10]+=i;
                System.out.println("x["+(i-10)+"]="+x[i-10]);
        }
}
}
5、throws:抛出的运行异常,这个在以后的章节中讲
6、方法体:一般来说,我们先定义变量后再使用可以使程序的可读性增强

TOP

第二十课  面向对象的基本概念(5)
类的设计
  我们先看下面的一个例子:
import java.io.*;
public class Myclass1{
public static void main(String args[])
{
char c=0;
System.out.print("Enter a character:");
try{
c=(char)System.in.read();
}catch(IOException e){};
if(c>=65&&c<=90||c>=97&&c<=122)
  System.out.println("It is a letter.The letter is:"+c);
else
  System.out.println("It's not a letter");
}
}
在这个例子中包括这样几个部分:
1、        接受键盘输入
2、        判断是否是字符
3、        看屏幕输出的结果
这种程序的可读性是比较差的,所以我们变一下:
import java.io.*;
public class Myclass1{
        public static void main(String args[])
        {
                Myclass1 test=new Myclass1();
                char x=test.input();
        test.output(x);
        }
        public Myclass1(){};
        public void output(char c){
                if(c>=65&&c<=90||c>=97&&c<=122)
      System.out.println("It is a letter.The letter is:"+c);
    else
      System.out.println("It's not a letter");
  }
  public char input(){
          char c=0;
    System.out.print("Enter a character:");
    try{
      c=(char)System.in.read();
     }catch(IOException e){};
     return c;
    }
  }
  在上面的例子中我们把输入输出分别用了output和input方法分别定义,显得结构更为清晰,如果处理过程过于复杂时,我们还可以写成几个类的形式:
===========生成文件Myclass1.java
import java.io.*;
public class Myclass1{
        public static void main(String args[])
        {
                Myclass1 test=new Myclass1();
                input myInput=new input();
                char x=myInput.getChar();
          test.output(x);
        }
        public Myclass1(){};
        public void output(char c){
                if(c>=65&&c<=90||c>=97&&c<=122)
      System.out.println("It is a letter.The letter is:"+c);
    else
      System.out.println("It's not a letter");
  }
}
===========生成文件input.java
import java.io.*;
public class input{
        public input(){}
        public char getChar(){
    char c=0;
    System.out.print("Enter a character:");
    try{
      c=(char)System.in.read();
     }catch(IOException e){};
    return c;
   }
  }
由于我们在这个程序中使用了两个类,而这两个类在同一个包中(由于我们把它放在了同一个文件夹下)
我们再看下面的例子:
public class Test{
  public static void main(String args[]){
    input Myinput=new input();
    Test Mytest=new Test();
    char x=Myinput.getChar();
    Mytest.output(x);
  }
  public void output(char c){
    System.out.println(c);
  }
}
在这个例子中我们又用到了input类,但由于在前面我们已经建立了它,所以我们在这里就可以不再建立了。

TOP

第二十一课  面向对象的基本概念(6)
一、        包(Package):这个有点类似于windows的文件夹的机制,他的出现使不同的程序员在完成一个大的程序的时候,不会发生命名的冲突,也就是类命的引用问题引发的冲突。我们把定义的类都加入某一个包中,并作为包的一部分存在,那么使用包的机制使每个Java中的变量和方法都可以用全限定的名字来表示,即包名、类名和成员名,各部分间用点号分隔即可。
   当源程序没有声明类所在的包时,Java将类放在默认的包中,这就意味着每个类必须使用惟一的名字,否则就会发生名字冲突。
   在JAVA中包是实现封装的一种手段,也是限定类中方法和变量的作用域的一种手段。它为类和其他的子包提供了一个“容器”,这个容器针对不同的访问级别来确定具体的访问范围。
   当类被声明为Public时,其代码可以把任何其它代码访问;而类没有被显式声明时(相当于friendly),可以被同一个包的其它代码访问,但除此之外的其它所有类不可见。
   定义方法:package  包名;
例:
package test;

public class Hello{
String hello1;
String hello2;
public Hello(){
hello1="Hello";
hello2=" Word!";
}
public void printHello(){
System.out.print(hello1);
System.out.print(hello2);
}
public static void main(String args[]){
Hello aa=new Hello();
    aa.printHello();
  }
}
注意:
1、包名必须与文件夹名一样
2、在运行时要加上包名.类名
3、正确设置好环境变量

TOP

第二十二课  面向对象的基本概念(7)
一、        构造方法:与类名相同,一旦定义了构造方法,在对象被创建时就可自动调用,它完成对实例变量进行初始化。与一般方法不同的是,构造方法没有返回类型,它的返回类型是隐式的,就是类型本身。
比如:
public class Car{
public int gearNum;
public int engine;
Car(){
  this.gearNum=0;
  this.engine=0.0;
}
Car(int x,float y){
  this.gearNum=x;
  this.engine=y;
}
}
在上面的例子中我们定义了两个同名的构造函数,这就是“构造函数的重载”,这个我们以后还要继续讲。
如果我们在定义一个类时,没有定义和类同名的构造函数,JAVA内部也会生成一个默认的构造函数,但不进行任何操作。
二、        this和super的使用
我们来看一个例子:
public class Leaf{
  private int i=0;
  Leaf increment(){
   i++;
     return this;
   }
  void print(){
    system.out.println(“I=”+i);
   }
   public static void main (string args[]){
    Leaf x=new Leaf();
    x.increment().increment().increment().print();
  }
}
在上面的例子中,this返回的是当前对象的地址,所以可以方便地对同一个对象执行多项操作。
而super和this有着不同的概念,如果子类的对象想使用它父类中的同名属性和方法时,就可以使用了。
如下例:
public class WordTest{
  int a;
  WordTest(int a){
     this.a=a;
   }
   WordTest(){
    this(5);
   }
}
public class SentenceTest extends WordTest{
  int b;
  SentenceTest{
    super(3);
    this.b=b;
   }
}
在以上程序段中其实this(5)中的this就代表了本类中的第一个构造方法,而在super(3)中调用了父类的构造方法。另外要注意的是super关键字必须放在当前构造方法的第一行。

TOP

第二十三课  面向对象的基本概念(8)

这节课我们给大家一个例子,仔细分析一下:
class Teacher{
        public Teacher(String n,double s,int a)
        {
                name=n;
                salary=s;
                age=a;
        }
        public void print(){
                System.out.println(name+"  "+salary+"  "+age);
        }
        public String getName(){
                return name;
        }
        public double getSalary(){
                return salary;
        }
        public int getAge(){
                return age;
        }
        private String name;
        private double salary;
        private int age;
}
以下调用Teacher类
public class TeacherTest{
        public static void main(String args[]){
                Teacher staff[]=new Teacher[3];
                staff[0]=new Teacher("张三",5000,34);
                staff[1]=new Teacher("李四",6000,32);
                staff[2]=new Teacher("王五",7000,30);
                int i;
                for(i=0;i<3;i++) staff.print();
                for(i=0;i<3;i++)
                {
                        System.out.println(staff.getName());
                        System.out.print("  "+staff.getSalary());
                        System.out.println("  "+staff.getAge());
                }
        }
}

本期无视频

[ 本帖最后由 黑雨 于 2006-12-18 09:05 AM 编辑 ]

TOP

第二十四课  继承(1)

一、继承:是一种由已知的类创建新类的机制。可以说继承是对父类的一种复制,子类在创建之时,不需进行任何定义,就能拥有父类私有的属性和方法。
   我们在程序设计时可能会遇到这样的问题,在定义时发现它的成员已经在另一个类中定义过了,如果再次定义就显得累赘,也不能反映这两个类的关系,所以面向对象的方法中引入了继承的概念。也就是一个类无需再定义就能拥有另一个类的属性和方法,通常先定义的类我们称为父类,后定义的类称子类。
   在JAVA中规定一个子类只能有一个父类。而一个父类可以拥有多个子类。
二、继承的定义:
  JAVA中通过关键字extends来定义两个类之间的继承关系,如:
Public class Automobile extends Vehicle{}
这里面Automobile为子类
       Vehicle为父类
但这并不固定化,如:
Public class Car extends Automobile{}
这里面Automobile为父类
       Car为子类
子类可以保持父类原有的属性和方法,也可以对父类那里继承来的属性和方法进行修改,从而继承关系成为一种非常灵活的技术。
如:
public class Vehicle{
   String color=”White”    //颜色属性
   Protect float speed;      //速度属性
   Public void accelerate(){  //加速度方法
   ·
   ·
   ·
}
当我们再定义Automobile的时候就含有了父类的所有属性和方法,并新增加了属性和方法
Public class Automobile extends Vehicle{
  Float fuelConsumption;   //燃油率属性
  Public void decelerate(){  //减速方法
   ·
   ·
   ·

}
如果再定义Car时又会继承两个类的属性和方法
Public class Car extends Automobile{}
  Private int price;
  Public void decelerate(){
   Speed=speed-20.f;
  }

TOP

第二十五课  继承(2)
这节课我相给大家讲一下,为什么要用继承,其实我们在上节课中已经讲了一些,那么看下面这个例子:
//例一
class ClassB{
  int doThis(){
//……
}
  int doThat(){
//……
}
}
这时假如发现ClassA中也提供了doThis()和doThat()方法,其中doThis()方法是一样的,但doThat()的方法有一点小的差异,于是我们改动一下:
class ClassB{
ClassA a=new ClassA();
Int doThis(){
  Return a..doThis();
}
int doThat(){
  return Math.abs(a.doThat());
}
}
这时候我们可以看出ClassA被嵌入到ClassB中了,ClassB把方法调用转发给ClassA来处理,程序似乎也不错,但如果ClassA还有一百个方法,而这一百个方法ClassB都要,于是出现了下面的代码:
class ClassB{
ClassA a=new ClassA();
Int doThis(){
  Return a..doThis();
}
int doThat(){
  return Maht.abs(a.doThat());
}
int method1(){
  return a.method1();
}
int method2(){
  return a.method2();
}
//若干重复代码
int method100(){
  return a.method100();
}
}
这个程序大家看怎么样,一定是太糟了,但我们引入了继承的机制就完全不一样了:
class ClassB extends ClassA{
  int doThat(){
return Math.abs(a.doThat());
}
这时我们在使用B的时候一样可以使用A的方法:
ClassB b=new ClassB;
b.doThis();
b.method1();

TOP

第二十六课  继承(3)
一、属性的继承:
1、子类被创建时,另外开辟了存储空间,其初值是父类中属性的初值
2、继承后双方的属性就是彼此独立的变量了,即父类中属性发生了改变,子类不变
3、父类中属性的类型发生了改变,子类会随之发生改变
我们看下面的例子:
public class Father{
        int a=100;
        public void miner(){
                a--;
        }
        public static void main(String args[]){
                Father x=new Father();
                Son y= new Son();
                System.out.println("a of son is :"+y.a);
                System.out.println("a of son'super is :"+y.getA());
                y.miner();
                System.out.println("a of son is :"+y.a);
                System.out.println("a of son'super is :"+y.getA());
        }
}
class Son extends Father{
        int a=0;
        public int getA(){
         return super.a;
        }
}
二、方法的继承
1、能够继承那些声明为public和protected的成员方法
2、能够继承同一包中的默认修饰符的成员方法
3、不能继承声明为private的方法
4、如果子类方法与超类方法同名,则不能继承(覆盖)
5、使用final修饰的方法是不能被子类覆盖的,只能重载
我们看这个例子:
class Person{
        String name;
        int age;
        void set(String s,int i){
                name=s;
                age=i;
        }
        public void print(){
                System.out.println(name+","+age);
        }
}
public class Student extends Person{
        protected String dept;
        public static void main(String args[]){
                Person p=new Person();
                p.set("Richard",23);
                p.print();
                Student stu=new Student();
                stu.set("Drodan",34);
                stu.dept="Computer";
                stu.print();
        }
}

下面的例子有点难:
class SuperClass{
        public final void afunction(){
                System.out.println("null!!!!!!");
        }
}
class Subbie extends SuperClass{
        public void afunction(int i){
                super.afunction();
                System.out.println("?????????????");
        }
}
public class TestOverride{
        public static void main(String args[]){
                SuperClass aa=new SuperClass();
                Subbie bb=new Subbie();
                aa.afunction();
                bb.afunction(90);
        }
}

TOP

发新话题