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

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…..一样),而每一个数组元素还未向程序申请,所以需要第二行代码。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值