美文网首页
13-面向对象

13-面向对象

作者: wangfs | 来源:发表于2018-07-11 19:10 被阅读8次

    内容:

    • final
    • static
    • 匿名对象
    • 内部类
    • 包的声明与访问
    • 四种访问修饰符
    • 代码块
    1. final关键字
    1.1 final的概念

    继承的出现提高了代码的复用性,并方便了开发。但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分功能是固定的,不想让子类重写。可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,那么怎么解决呢?

    要解决上述的这些问题,需要使用一个关键字final,final的意思为最终,不可变。final是一个修饰符,它可以用来修饰类,类的成员,类的方法,类的对象,以及局部变量。

    1.2 final的特点
    • final修饰的类不可以被继承,但是它可以继承其他类。
    //一个final修饰的父类
    package test01;
    
    public final  class Fu {
        
    }
    
    package test01;
    /*
     * 被final修饰的父类不可以被子类继承
     * 下面这种写法会报错
     * */
    public class Zi  extends Fu{
    
    }
    
    • final修饰的方法不可以被覆盖,但父类中没有被final修饰方法,子类覆盖后可以加final。
    package test01;
    //建一个父类
    public   class Fu {
        //final修饰的方法不可以被子类覆盖,但是可以被子类继承使用
        public final void method_1() {
            System.out.println("Fu类的final方法");
        }
        public void method_2() {
            System.out.println("Fu类的非final方法");
        }
    }
    //建一个继承父类的子类
    package test01;
    /*
     * 被final修饰的父类不可以被子类继承
     * */
    public class Zi extends Fu{
            //重写父类方法
            public void method_2() {}
            
    }
    //建一个测试类
    package test01;
    
    public class TestDemo {
    
        public static void main(String[] args) {
            Zi z = new Zi();
            z.method_1();
            z.method_2();
    
        }
    
    }
    //运行TestDemo,则输出:
    Fu类的final方法
    //因为子类重写了父类的方法,但是方法体内并没有实际的语句,打印内容为空。所以仅打印出父类的method_1()方法的内容。
    
    • final修饰的变量称为常量,这些变量只能被赋值一次
    package test01;
    
    public class finalDemo {
    
        public static void main(String[] args) {
    
        
        }
        final int a = 1;
        
        public void function() {
            //a = 2; 此处再给a赋值就会报错
            System.out.println(a);
        }
    
    }
    
    • 引用类型的变量值为对象地址值,地址值不能修改,但是地址内的对象属性值可以修改。
    package itcast01;
    //创建一个Person类
    public class Person {
    //类的属性
        String name;
        String age;
    }
    //创建一个测试类
    package itcast01;
    
    public class TestDemo {
    
        public static void main(String[] args) {
            //创建一个final修饰的Person类对象
            final Person p = new Person();
            Person p2 = new Person();
            // p = p2; 报错,final修饰的引用变量p,所记录的地址值不能被改变
            p.name = "小明";//但是可以更改p对象中name属性值
            
        }
    
    }
    //p不能为别的对象了,但是p对象中的name或age属性值可以更改
    
    • final修饰成员变量,需要在创建对象前赋值,否则会报错。(当没有显示赋值时,多个构造方法的均需要为其赋值)
    package itcast01;
    
    public class Demo {
        //直接赋值
        final int m = 100;
        
        //final修饰的成员变量,需要在创建对象前赋值,否则会报错
        final int n;
        //Demo类的构造方法
        public Demo() {
            //可以在创建对象时所调用的构造方法中,为变量n赋值
            n = 2018;
        }
    }
    
    2. static 关键字
    2.1 static概念

    当在定义类的时候,类中都会有相应的属性和方法。而属性和方法都是通过创建本类对象调用的。当在调用对象的某个方法时,这个方法没有访问到对象的特有数据时,为了调用方法而创建这个对象就有些多余了。可是不创建对象,方法又调用不了,这时就会想,我们能不能不创建对象,就可以调用方法呢?
    可以的,我们可以通过static关键字类实现,static它是静态修饰符,一般用来修饰类中的成员。

    2.2 static特点
    • 被static修饰的成员变量属于类,不属于这个类的某个对象。(也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量跟着改变,即多个对象共享同一个static成员变量)
    package itcast02;
    
    public class Demo {
        //被static修饰的成员变量。此成员变量属于这个类,不属于这个类的某个对象。
        public static int num = 100;
        
    }
    //测试类
    package itcast02;
    
    public class Test {
    
        public static void main(String[] args) {
            Demo d1 = new Demo();
            Demo d2 = new Demo();
            //d1对象修改了类成员变量的值
            d1.num = 200;
            System.out.println(d1.num);//结果为200
            
            //d1对象修改了类成员变量的值,其他对象中的static成员变量也跟着修改
            System.out.println(d2.num);//结果为200
        }
    
    }
    
    • 被static修饰的成员变量可以并且建议通过类名直接访问
      访问静态成员的格式:
      类名.静态成员变量名
      类名.静态成员方法名(参数)
      对象名.静态成员变量名 --- 不建议使用该方式,会出现警告
      对象名.静态成员方法名(参数) -- 不建议使用该方式,会出现警告
    package itcast03;
    
    public class Demo {
        //静态成员变量
        public static int  num = 100;
        //静态方法
        public static void method() {
            System.out.println("静态方法");
        }
    }
    
    //测试类
    package itcast03;
    
    public class Test {
    
        public static void main(String[] args) {
            //直接访问Demo类的成员变量
            System.out.println(Demo.num);
            //直接调用Demo类的方法
            Demo.method();
        }
    
    }
    
    • 静态内容是优先于对象存在的,只能访问静态,不能使用this/super。静态修饰符的内容存在于静态区。
      static01.png
      如果注释掉System.out.println(this.num);则正常。
    2.3 开发中,我们想在类中定义一个静态常量,通常使用public static final 修饰的变量来完成定义。此时变量名要全部大写,多个单词使用下划线连接。

    定义格式:
    public static final 数据类型 变量名 = 值;

    package itcast04;
    
    public class Company {
    
        //定义一个静态常量
        public final static String THIS_NAME = "好厉害公司";
        //定义一个静态方法
        public static void method() {
            System.out.println("这是一个静态方法。");
        }
    }
    //测试类
    package itcast04;
    //当我们使用类的静态成员时,不需要创建类的对象,直接使用类名来访问即可
    public class Test {
    
        public static void main(String[] args) {
            //直接调用类的静态方法
            Company.method();
            //直接调用类的静态常量
            System.out.println(Company.THIS_NAME);
    
        }
    
    }
    
    • 注意:
      接口中的每个成员变量都默认使用public static final修饰
      所有接口中的成员变量已经是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
    package itcast04;
    
    public interface InterfaceDemo {
        //接口中的成员变量
        public static final int COUNT = 100;
    }
    
    //测试类
    package itcast04;
    
    public class TestInterface {
    
        public static void main(String[] args) {
            //直接接口名访问接口中的成员变量
            System.out.println(InterfaceDemo.COUNT);
        }
    
    }
    
    3 匿名对象
    3.1 匿名对象的概念

    匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址赋值给某个变量。
    如:已经存在的类:

    package itcast04;
    
    public class Person {
        public void eat() {
            System.out.println("人在吃饭");
        }
    }
    //创建对象
    package itcast04;
    
    public class TestPerson {
    
        public static void main(String[] args) {
            //创建一个普通对象
            Person p = new Person();
            //创建一个匿名对象
            new Person();
        }
    
    }
    
    32. 匿名对象的特点
    • 创建匿名对象直接使用,没有变量名。
    package itcast04;
    
    public class TestPerson {
    
        public static void main(String[] args) {
            //创建一个普通对象
            Person p = new Person();
            //创建一个匿名对象
            new Person();
            
            //直接使用匿名对象
            new Person().eat();//eat方法被一个没有名字的Person对象调用了。
        }
    
    }
    //注意:匿名对象在没有指定其引用变量是,只能使用一次。如果想再次调用eat方法,则必须重新创建一个匿名对象。
    
    • 匿名对象可以作为方法接收的参数,方法返回值使用。
    package itcast.demo01;
    //创建Person类
    public class Person {
        String name = "张三" ;
        int age= 20;
    }
    
    
    package itcast.demo01;
    //创建一个类,包含静态方法,可以被直接调用
    public class Demo {
        public static Person getfunction() {
            //普通方式
            //Person p = new Person();
            //return p;
            
            //匿名对象作为方法的返回值
            return new Person();
            
        }
        
        //匿名对象作为方法的参数
        public static void method(Person p) {
            System.out.println(p.name);
            System.out.println(p.age);
        }
    }
    
    //创建测试类
    package itcast.demo01;
    
    public class Test {
    
        public static void main(String[] args) {
            //直接调用Demo的静态方法
            Person p = Demo.getfunction();
            System.out.println(p.age);
            System.out.println(p.name);
            
            //调用method方法
            Demo.method(p);
            
            //匿名对象作为参数传递给方法
            Demo.method(new Person());
            
    
        }
    
    }
    
    4 内部类
    4.1 内部类概念
    • 什么是内部类
      将类写在其他类的内部,可以写在其他类的成员位置和局部位置,这时写在其他内部类的类就称为内部类。其他类则称为外部类。
    • 什么时候使用内部类
      在描述事物时,若一个事物内部还包含其他可能包含的事物,比如在描述汽车时,汽车中还包含着发动机,这时发动机就可以使用内部类来描述。
    //伪代码
    class 汽车 {//外部类
        class 发动机 {//内部类
      }
    }
    
    • 内部类的分类
      内部类分为成员内部类与局部内部类
      我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符、继承与实现关系等。

    在内部类中可以直接访问外部类的所有成员。

    4.2 成员内部类

    成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问。

    • 定义格式
    //伪代码
    class 外部类{
        修饰符 class 内部类{
              //其他代码
          }
     }
    
    • 访问方式
      外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

    • 成员内部类代码演示

    package itcast.demo01;
    
    public class body { //外部类,身体
        private boolean life = true;//生命状态
        public class Heart {//内部类
            //内部类的方法
            public void jump() {
                System.out.println("心脏噗通噗通的跳");
                System.out.println("生命状态"+life);//访问外部类的成员变量
            }
        }
    }
    

    访问内部类

    package itcast.demo01;
    //访问内部类
    public class TestBody {
    
        public static void main(String[] args) {
            //创建内部类对象
            //外部类名.内部类名 变量名 = new 外部类名.new 内部类名();
            body.Heart bh = new body().new Heart();
            
            //调用内部类中的方法
            bh.jump();
        }
    
    }
    
    4.3 局部内部类

    局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量类似,可通过调用方法进行访问。

    • 定义格式:
    class 外部类{
          修饰符 返回值类型 方法名(参数){
                     class 内部类 {
                              //其他代码
                                }  
                  }
    }
    
    • 访问方式
      在外部类方法中,创建内部类对象,进行访问
    • 局部内部类代码演示
    package itcast04;
    
    public class Party { //外部类
        public void puffBall() {//吹气球方法
            class Ball {//局部内部类,气球
                    public void puff() {
                        System.out.println("气球膨胀了");
                    }
                }
            //创建内部类对象,调用puff方法
            new Ball().puff();
            }
        }
    

    访问内部类

    package itcast04;
    //访问内部类
    public class TestParty {
    
        public static void main(String[] args) {
            //创建外部类对象
            Party p = new Party();
            //访问内部类的puffBall方法
            p.puffBall();//会输出 "气球膨胀了"
        }
    
    }
    
    4.4 内部类的实际使用--匿名内部类
    4.4.1 匿名内部类概念

    内部类是为了应对更为复杂的类间关系。查看源码中会涉及到,而在日常业务中很难遇到,这里不做赘述。
    最常用到的内部类就是匿名内部类,它是局部类的一种。
    定义的匿名内部类有两个含义;

    • 临时定义某一指定类型的子类
    • 定义后即刻创建刚刚定义的这个子类的对象
    4.4.2 定义匿名内部类的作用与格式

    作用:匿名内部类是创建某个类型子类对象的快捷方式
    格式:

    new 父类或接口(){
        //进行方法重写
    };
    
    • 代码演示:
    package itcast04;
    //定义一个抽象类
    public abstract class Person01 {
        public abstract void eat();
    }
    
    //定义测试类
    package itcast04;
    //定义并创建Person01的子类对象,并用多态的方法赋值给父类引用变量
    //注意这里是"定义并创建"。同时,抽象的父类和接口是不能直接new对象的。此处new出来的是子类对象
    public class Person01_zi {
    
        public static void main(String[] args) {
            Person01 p = new Person01() {
                public void eat() {
                    System.out.println("您吃过了吗?");
                }
            };
            //调用eat方法
            p.eat();
        }
    
    }
    

    使用匿名对象的方式,将定义子类与创建子类对象两个步骤由一个格式一次完成。虽然是两个步骤,但是两个步骤是连在一起完成的。
    匿名内部类如果不定义变量引用,则也是匿名对象。代码如下:

    new Person01() {
                public void eat() {
                    System.out.println("您吃过了吗?");
                }
            }.eat();
    

    注意事项:
    在使用匿名内部类的过程中,我们需要注意如下几点:

     1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
    
     2、匿名内部类中是不能定义构造函数的。
    
     3、匿名内部类中不能存在任何的静态成员变量和静态方法。
    
     4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
    
     5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
    

    参考:http://www.cnblogs.com/chenssy/p/3390871.html
    站点:http://cmsblogs.com/

    相关文章

      网友评论

          本文标题:13-面向对象

          本文链接:https://www.haomeiwen.com/subject/huhkpftx.html