Java日记(7)— 访问控制符

来源:互联网 发布:淘宝客网站建站 编辑:程序博客网 时间:2024/06/05 23:52

1.static:

代码一(类变量):

特点:1.类变量可以通过类名直接访问,而不需要创建对象     2.任何一个对象对类变量的修改,都是在统一内存单元上完成的。因此,每个对象对类变量的修改都会影响其他实例对象。
package package2;public class Example_5_19 {    public static void main(String[] args) {            System.out.println("目前出生的人数:"+Person.totalNum);            Person Wang =new Person("Wang");            Person Liu = new Person("Liu");            Person Zhao = new Person("Zhao");            System.out.println("目前出生的人数:"+Person.totalNum);            System.out.println("目前出生的人数:"+Wang.totalNum);    }}class Person{    static long totalNum=10000;    int age;    String name;    String id;    //    public Person(String name){        totalNum++;        this.name=name;        age=1;    }}



代码二(类方法):

特点:1.类方法可以通过类直接调用,而不需要创建实例对象。例如,java Application的入口main()方法被声明为static类方法,不需要创建任何对象即可调用。     2.类方法属于整个类,被调用时可能还没有创建实例对象,因此,(重点哦!)类方法内只能访问类变量,而不能直接访问实例变量和方法     3.类方法中不能使用this关键字,因为类方法不属于任何一个实例
public class Example_5_20 {    public static void main(String[] args) {        System.out.println(staticTestFunction.addUP(10,5));//类方法可以被类调用        //System.out.println(staticTestFunction.sub());     //ERROR:类不可调用实例方法        staticTestFunction test = new staticTestFunction();        System.out.println(test.sub());    }}class staticTestFunction{    int x=10,y=6;    static int z=9;    public static int addUP(int a,int b){   //被声明为类方法        return a+b+z;                       //类方法中使用类变量    }    public int sub(){        return x-y;    }    public static int addUP(){    //  return x+y;                         //ERROR:类方法中不能使用实例变量    }}

2.final(const ):

被final修饰的类,成员变量,成员方法均不允许继承或者覆盖。

3.abstart(virtual):

声明一个类为抽象类。语法:abstract class <类名> [extends<父类>][implements<接口名>]{<类主体>}

代码:

package package2;public class Example_5_22 {    public static void main(String[] args) {        //Animal a new Animal();    //禁止实例化抽象类        Cat2 Tom = new Cat2();        Tom.eat();        Tom.run();    }}abstract class Animal1{         //抽象类    String eyeColor;    String furColor;    int age;    //    public Animal1(){        age =0;    }    abstract void eat();        //抽象函数,没有方法体    abstract void run();        //抽象函数,没有方法体}class Cat2 extends Animal1{    void run(){                     System.out.println("猫扑");    }    void eat(){        Syst`m.out.println("吃老鼠");    }}

4.其他修饰符(具体用法请百度):

1.volatile
2.native
3.synchronized

5.接口:

接口(interface)是java所提供的另一种重要结构。
接口是一种特殊的类,但接口与类存在本质的区别。
类有成员变量和成员方法,但接口却只有常量和抽象方法。也就是说,接口的成员必须初始化,同时接口中的方法必须声明为abstract方法。

定义:[接口修饰符] interface<接口名>[extends<父类接口列表>]{接口体}
  1. 接口修饰符:接口修饰符为接口访问权限,有public和默认两种类型。 public指明任意类均可以使用这个接口。 在默认情况下,只有与该接口定义在同一包中的类才可以访问这个接口,而其他包中的类无权访问该接口
  2. 接口名:接口名为合法的Java语言标识符
  3. 父类接口列表:一个接口可以继承其他接口,可通过extends来实现,其语法与类的继承相同。被继承的类接口成为父类接口,用逗号(,)分隔
  4. 接口体:接口体中包括接口中需要说明的常量和抽象方法。由于接口体中只有常量,所有接口中的成员变量中只能定义static和final型,在类实现接口时不能修改,而且必须用常量初始化。接口体中的方法说明与类中的方法说明形式是一样的,由于接口体中的方法说明与类中的方法说明形式一样,由于接口体中的方法为抽象方法,所以没有方法体,抽象方法的关键字abstract是可以省略的,同时成员变量的关键字final也可省略。
  5. 接口体中的方法多被说明成public权限

6.内部类与匿名类:

代码(内部类):

package package2;import package2.Parcel.Destination;public class Example_5_23 {    public static void main(String[] args) {        Parcel p = new Parcel();        Parcel.Contents c =p.new Contents(33);        Parcel.Destination d =p.new Destination("山西大同");        //Destination d = new Destination("山西太原");        p.setValue(c,d);        p.ship();        p.testship();    }}class Parcel{    private Contents c;    private Destination d;    private int contentsCount =0;    class Contents{        private int i;        Contents(int i){            this.i = i;            contentsCount++;        }        int value(){            return i;        }    }    class Destination{        private String label;        Destination(String whereto){            label = whereto;        }        String readLabel(){            return label;        }    }    void setValue(Contents c,Destination d){        this.c=c;        this.d=d;    }    void ship(){        System.out.println("运输"+c.value()+"到"+d.readLabel());                              }    public void testship(){        c = new Contents(22);        d = new Destination("山西太原");        ship();    }}

说明:
程序编译后生成4个类文件:Example_5_23.class,Parcel.class,Parcel$Contents.class,Parcel$Destination.class

特点:1.外部类使用内部类成员。外部类使用内部类同其他成员变量和成员方法没有区别。如在例子中,Parcel类的ship方法中可以直接使用Destination和Contents类的方法和成员变量     2.内部类使用外部类的成员。一个类把内部类堪称自己的成员,外部类的成员变量在内部类中依然有效,<b>内部类可以直接使用外部类中的成员变量和方法,即便他们是private的</b>,这也是内部类的一个好处。如果内部类与外部类有同名的成员变量,<b>可以使用:外部变量名.this来访问外部类张同名的成员变量。</b>     3.非外部类使用内部类。非外部类的其他类使用内部类,在用类名和new运算符前分别冠以外部类的名字及外部对象类;不能直接使用内部类(注释)。

代码(匿名类):

package package2;abstract class Student5{    abstract void speak();}class Teacher2{    void look(Student5 s){              s.speak();    }}public class Example_5_24 {    public static void main(String[] args) {        Teacher2 zhang = new Teacher2();        /******************************************************/        Student5 liu = new Student5(){            void speak(){                System.out.println("这是匿名类中的方法");            }        };        /*****************************************************/        zhang.look(liu);            }}

7.泛型类(模板):

package package2;public class Example_5_27 {    public static void main(String[] args) {        Circle3 circle = new Circle3(10);        Cone<Circle3> oneCone = new Cone<Circle3>(circle);        oneCone.height =10;        oneCone.computeVolume();        Rctangle rectangle = new Rctangle(10,5);        Cone<Rctangle> anotherCone = new Cone<Rctangle>(rectangle);        anotherCone.height = 30;        anotherCone.computeVolume();    }}class Cone<E>{              //泛型类    E bottom;    double height;    public Cone(E b){        bottom = b;    }    public void computeVolume(){        String s = bottom.toString();        double area = Double.parseDouble(s);        System.out.println("体积是:"+1.0/3.0*area*height);    }}class Circle3{    double area,radius;    Circle3(double r){        radius = r;    }    public String toString(){        area = radius * radius * Math.PI;        return ""+area;    }}class Rctangle{    double sideA,sideB,area;    Rctangle(double sideA,double sideB){        this.sideA = sideA;        this.sideB = sideB;    }    public String toString(){        area = sideA * sideB;        return ""+area;    }}

泛型接口:
代码:

package package2;public class Example_5_28 {    public static void main(String[] args) {        Chorous4<Singer2,MusicalInstruments2> model = new Chorous4<Singer2,MusicalInstruments2>();        model.makeChorous(new Singer2(), new MusicalInstruments2());    }}interface Compute<E,F>{    void makeChorus(E x,F y);}class Chorous4<E,F> implements Compute<E,F>{    public void  makeChorous(E x, F y){        x.toString();        y.toString();    }}class Singer2{    public String toString(){        System.out.println("好一朵美丽的茉莉花");        return "";    }}class MusicalInstruments2{    public String toString(){        System.out.println("|8555555555555");        return "";    }}



遇到的坑(和本节内容无关,这几天敲代码时遇见的)
一:

用命令行编译运行代码时,需要注意:1. javac Class.java (带后缀);   java Class(不带后缀)2.在Class.java中不能声明所属包(或者可以声明,只是我不知道)

二:
声明对象数组时,注意每个数组元素也要初始化,及:

    Student [] stu = new Student[30];    stu[0].getInfo();                //报错 Exception in thread "main" java.lang.NullPointerException ,指针指向的是空的,及指针未初始化    修改:    Student [] stu = new Student[30];    Student[0] = new Student();    Student[0].getInfo();

仔细体会未修改和修改的区别:

Student [] stu = new Student[30]只是向程序说明了有一个指向大小为30个Student数量的数组,然后分配‘数组’的空间(及相当于写了30个 Student stu1,2.3,4,5…..一样),而每一个数组元素还未向程序申请,所以需要第二行代码。

异常中最容易,最平凡出现的就是空指针的问题,一定要看仔细,当出现空指针的异常时,转到错误的内行仔细分析,冷静下来,相信总会找到问题的