2019-08-10 java内部类,重写,代码块,多态,继承

目的

学习关于:

1.定义和使用内部类

2.内部类和外部类之间的调用规则

3.子类对父类有访问权限的方法的重写和使用

4.几种代码块的使用范围和执行顺序以及区别

5.多态的优点和用法

6.java继承的规则和使用

技术及其方法

1.内部类

成员内部类:定义在另一个类的内部的类,是最普通的内部类
class Outter{
        public int a;
        public int b;
        public Outter(int a,int b){
        this.a = a;
        this.b=  b
      }
class Inner{
        public void DrawInner(){
        System.out.println("i'm Inner");
}
}
}
这样看起来,类Inner像是类Outter的一个成员,Outter称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
注意:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
class Outter{
        public int a;
        public int b;
        public Outter(int a,int b){
        this.a = a;
        this.b=  b
         getDrawInnnerInstance.DrawInner();
         
      }
public DrawInner getDarwInnerInstance(){
      return new DrawInner();
}
class Inner{
        public void DrawInner(){
        System.out.println("i'm Inner");
}
}
}
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
class Circle {
    private double radius = 0;
 
    public Circle(double radius) {
        this.radius = radius;
        getDrawInstance().drawSahpe();   //必须先创建成员内部类的对象,再进行访问
    }
     
    private Draw getDrawInstance() {
        return new Draw();
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println(radius);  //外部类的private成员
        }
    }
}
成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:
public class Test {
    public static void main(String[] args)  {
        //第一种方式:
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  //必须通过Outter对象来创建
         
        //第二种方式:
        Outter.Inner inner1 = outter.getInnerInstance();
    }
}
 
class Outter {
    private Inner inner = null;
    public Outter() {
         
    }
     
    public Inner getInnerInstance() {
        if(inner == null)
            inner = new Inner();
        return inner;
    }
      
    class Inner {
        public Inner() {
             
        }
    }
}
内部类可以拥有 private 访问权限、protected 访问权限、public 访问权限及包访问权限。比如上面的例子,如果成员内部类 Inner 用 private 修饰,则只能在外部类的内部访问,如果用 public 修饰,则任何地方都能访问;如果用 protected 修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被 public 和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。

2.重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写。重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法
class Animal{
   public void move(){
      System.out.println("动物可以移动");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 对象
      Animal b = new Dog(); // Dog 对象
 
      a.move();// 执行 Animal 类的方法
 
      b.move();//执行 Dog 类的方法
   }
}

以上实例编译运行结果如下:

动物可以移动
狗可以跑和走

方法的重写规则:
1.参数列表必须完全与被重写方法的相同。
2.返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
3.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
4.父类的成员方法只能被它的子类重写。
5.声明为 final 的方法不能被重写。
6.声明为 static 的方法不能被重写,但是能够被再次声明。
7.子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
8.子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
9.重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
10.构造方法不能被重写。
11.如果不能继承一个方法,则不能重写这个方法。

Super 关键字的使用

当需要在子类中调用父类的被重写方法时,要使用 super 关键字。

class Animal{
 public void move(){
    System.out.println("动物可以移动");
 }
}

class Dog extends Animal{
 public void move(){
    super.move(); // 应用super类的方法
    System.out.println("狗可以跑和走");
 }
}

public class TestDog{
 public static void main(String args[]){

    Animal b = new Dog(); // Dog 对象
    b.move(); //执行 Dog类的方法

 }
}

以上实例编译运行结果如下:

动物可以移动
狗可以跑和走

3.代码块

一.静态代码块:在java类中(方法中不能存在静态代码块)使用static关键字和{}声明的代码块:
public class CodeBlock {
    static{
        System.out.println("静态代码块");
    }
}
1.静态代码块在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数
2.一般情况下,如果有些代码需要在项目启动的时候就执行,这时候就需要静态代码块。
3.静态代码块不能存在任何方法体中
4.静态代码块不能访问普通变量

二.构造代码块:在java类中使用{}声明的代码块(和静态代码块的区别是少了static关键字):
public class CodeBlock {
    static{
        System.out.println("静态代码块");
    }
    {
        System.out.println("构造代码块");
    }
}
1.构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优先于构造函数执行。

4.多态

1.多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。
2.多态存在的三个必要条件

1.继承
2.重写
3.父类引用指向子类对象

比如:
Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
Test.java 文件代码:
public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

执行以上程序,输出结果为:

吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠

5.继承

承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
//类的继承格式
class 父类 {
}
 
class 子类 extends 父类 {
}
注意: Java 不支持多继承,但支持多重继承。
2019-08-10 java内部类,重写,代码块,多态,继承_第1张图片
继承

1.子类拥有父类非 private 的属性、方法。

2.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

3.子类可以用自己的方式实现父类的方法。

4.Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

实际使用

class Person{
    String name;
    int age;
    public void walk(){
        System.out.println("Person walking...");
    }
    public void eat(){
        System.out.println("Person eating...");
    }
}
class CivilServant extends Person{
    public CivilServant(String name,int age,int salary,int magazinenumber){
        this.name =name;
        this.age =age;
        this.salary =salary;
        this.magazinenumber =magazinenumber;
    }

    int salary;
    int magazinenumber;
    public void show(){
        System.out.println("  name:  "+name+"  age:  "+age+"  salary:  "+salary+"  magazinenumber:  "+magazinenumber);
    }
}
class Clerk extends Person{
    public Clerk(String name,int age,int salary,String tec){
        this.name =name;
        this.age  = age;
        this.salary =salary;
        this.tec = tec;
    }
    int salary;
    String tec;
    public void show(){
        System.out.println("  name:  "+name+"  age:  "+age +"  salary:  "+salary+"  tec:  "+ tec);
    }
}
 class TestMyDemo{
    public static void main(String[] args){
        String[] tecs = new String[]{"computer","ps","pr","au"};
        Person person1=new CivilServant("joy",17,2000,5);
        Person person2 =new CivilServant("envy",18,3000,7);
        Person person3 = new Clerk("sad",20,4000,"ps");
        Person person4 = new Clerk("scare",21,9000,"pr");

        ArrayList people = new ArrayList<>();
        people.add(person1);
        people.add(person2);
        people.add(person3);
        people.add(person4);

          ((CivilServant) person1).show();
        ((CivilServant) person2).show();
        ((Clerk) person3).show();
        ((Clerk) person4).show();


    }

tired

你可能感兴趣的:(2019-08-10 java内部类,重写,代码块,多态,继承)