Java学习笔记(06)

  • 继承
  • super关键字
  • 重写
  • final关键字
  • 抽象类/abstract关键字
  • 接口

一.继承

继承是类与类之间的继承,是一种is a 的关系(继承的满足条件)

继承的类叫子类 / 派生类,被继承的叫父类 / 基类

 

Java中的继承也是单继承

 

1.extends关键字

通过extends关键字来实现继承关系的

class 子类名 extends 父类名 {……}

class Fu
{…}
class Sub extends Fu
{…}

 

2.好处

1.优化代码。减少代码的重复使用。

2.复用代码。子类如果继承父类,就拥有了父类的方法和属性,子类可以复用父类的方法和属

 

3.继承的使用注意点

  1.不要为了继承而继承。两个类必须存在is a 的关系

   2.子类不允许继承父类的构造方法

    3.子类继承了父类,在调用自己的构造方法时,如果父类没有写有参的构造方法,系统会默认优先调用父类的构造方法

如果父类中写了有参的构造方法,系统就不会调用无参的构造方法,则子类不能调用到父类的构造方法导致报错

a)      解决办法:

    1. 方案一.在父类中添加无参构造方法让子类调用

    2.方案二.在子类的构造方法里第一个语句添加super关键字及传入参数 

 

//—>常犯错题1*******************************

class Fu {

         String name;

         String color;

         public Fu(String name, String color) {       //1.继承中不能调用父类的构造方法

                   this.name = name;                                                

                   this.color = color;

         }

         public Fu() {  //在父类中添加无参构造方法让子类调用

         }
}

class Sub extends Fu {

         int age;

         public Sub(int age, String name, String color) {  

                   super(name,color);   //  使用super关键字及传入参数,必须放在第一语句

                   this.age = age;     //this调用自己的构造方法  super();调用父类的构造方法

                   this.name = name;     

                   this.color = color;

        }
}

4.      如果用private修饰的属性和方法不能继承

5.      子类不能够继承在同一个包

 

为什么会调用父类的构造方法?

           子类在创建对象的时候先初始化父类的变量

 

 

4.权限修饰符

在添加变量的时候,不加权限修饰符,默认是friendly修饰,而不是public

 

访问权限

 

 

 

子类

 

其它包

public

protect

×

default

×

×

private

×

×

×

 

5.Super关键字

指向父类对象的引用空间

super关键字:用来初始化父类的属性和方法

 

1.super关键字的使用:

      1.当子类和父类的成员变量在重写同名的时候,可以通过super来访问父类的成员变量

      2.super可以调用父类的构造方法

 

//—>常犯错题*******************************

class Fu {

         String name = "张三";

         String color;

         public Fu(String name, String color) {

                   this.name = name;

                   this.color = color;

         }

}

class Zi extends Fu

{

         int age;

 

         public Zi(int age, String name, String color) {

                   super(name,color);

                   this.age = age;

         }

 

         public void run() {

                   //System.out.println(name + "调用了方法"); //默认在name前面隐式性的加了this关键字,调用当前自己的成员变量

                   System.out.println(super.name + "调用了方法");  //****使用super关键字,优先调用父类的属性,然后子类创建的对象,同时给参数赋值会覆盖父类中name的值,所以调用super还是李四

         }

}

 

2.super使用注意点:

      1.在子类的构造方法中调用父类的无参构造方法时用super语句,必须放在第一句

      2、super只能出现在子类的方法中,常用来调用父类的构造方法

    3、super和this不能够同时调用构造方法。因为两个在子类调用时构造方法时,都需要放在第一位,造成冲突

 

3.super和this的区别:

      1.对象不一样:

           this:当前方法的调用对象。

           super:表示父类对象的引用空间。

 

        2.条件不一致:

           super: 只能在继承的条件下使用。

           this: 没有限制。

 

        3.调用的构造方法不一样:

           super :调用父类的构造方法

           this : 调用本类构造方法

二.方法的重写

1.作用:

当父类的方法满足不了子类的实现,这个时候就通过复写来实现父类的行为,来保持自己特性

 

2.注意点:

  1. 有继承关系
  2. 子类和父类的方法名、形式参数要一致
  3. 子类重写父类的方法,会优先调用子类的方法,有可能导致父类的方法不能使用???
  4. 子类的权限修饰符必须要大于或等于父类的权限修饰符
  5. 子类的返回值类型必须小于或等于父类的返回值类型

    但是int类型必须保持一致

class Animl {

       public int run() {
              return 100;
       }

}

class Cat extends Animl {

       // 重写父类的方法

public int run() {   //父类的是返回值int类型,子类中的是double类型,也会报错:double与int类型不兼容

              return 100;
       }

}

 

 6.和方法的重载加以区分:重载时方法名一样,参数列表的个数、类型或顺序不一样

7子类的异常类型要小于或等于父类的异常类型

 

 

3继承中的初始化顺序:

先初始化父类的属性和方法,然后才初始化子类的属性和方法

 

 

4.Instanceof(实例类型)关键字的作用:

1.    判断某一个对象是否由这个类创建

2.    使用前提:继承关系

语法:对象 instanceof 类名;

 

//在Student类继承于Person类

class Demo {

         public static void main(String[] args) {

                   //判断p对象是否属于Person类

                   Person p = new Person();

                   boolean b1 = p instanceof Person;

                   System.out.println(b1);  //true 表示这个对象是这个类创建的

                   Student s = new Student();

                   boolean b2 = s instanceof Person; //必须满足继承Person类

                   System.out.println(b2);  //true 表示这个对象是这个类创建的

         }

}

 

5.final关键字

final关键字作为修饰符,可理解为最终的意思

1.final修饰的类型:

  1. 类:修饰的类将不能被继承
  2. 方法:修饰的方法将不允许重写(覆盖)
class  Yuan{

       int r;
       public final static double pi = 3.14;  //final修饰的属性时可直接赋值,而且只能赋值一次

       public Yuan(int r) {
              this.r = r;
       }

       public void area() {   //final修饰的属性不能在构造方法中初始化
              System.out.println("圆的面积是:" + r*r*pi);
       }
}

class  Demo{    //常见错误点**********

       public static void main(String[] args) {
final Yuan yu = new Yuan(10); yu.area(); //参数列表中的变量是都是局部变量,所以在两个方法中的值是互不影响的 test(yu); } public static void test(Yuan you) { you = new Yuan(20); //******创建了一个新的地址,所以可以改变值,这儿的形参名可以和上面主函数传递进来的参数不一样,两个都是指向的是不同一个内存空间 you.area(); } }

 

final的内存分析图:

 

 

3.    属性final修饰的属性必须初始化而且只能初始化一次

可在添加属性直接赋值,在没有添加static修饰的时候,也可在构造方法或主方法中赋值,但是不能再普通方法中给final初始化

 

4.变量:变量的值必须赋值一次而且只能赋值一次,赋值过后的变量就变成了常量(常量:不能改变的量)。不管是修饰基本数据类型还是引用数据类型,第一次的结果为最终的结果,修改值将会报错

为什么只能初始化一次?在没有final修饰的属性中,即使你没给它赋值,系统会给它一个隐式的默认值,但是用final修饰的时候,没有给它初始化的话是没有值的,所有会报错

 

Final修饰常量语法:public final static基本数据类型变量名

 

 

2.两个值的交换Demo  :

public static void main(String[] args)  {

                   int a = 10;

                   int b = 20;

                   //定义一个方法交换,基本数据类型之间的赋值,实际是直接把值赋给变量,并没有作交换

                   change(a, b);

                   System.out.println("a = " + a + "," + "b = " + b);

                   //定义一个方法交换,引用数据类型之间的赋值,实际是地址之间的交换来达到目的


                   int[] arr = {10, 20};

                   changeArr(arr);

                   System.out.println("a = " + arr[0] + "," + "b = " + arr[1]);

         }

         public static void change(int a, int b) {   //值没有交换

                   int tmp = a;
                   a = b;
                   b = tmp;

         }

         public static void changeArr(int[] arr) {  //交换了

                   int tmp = arr[0];
                   arr[0] = arr[1];
                   arr[1] = tmp;

         }

如果形式参数是基本数据类型,传递的就是值

如果形式参数是引用类型,传递的参数是地址

 

交换值的内存分析图

 

 

三.抽象类

用关键字abstract

背景:在重写父类时,可以不写父类的方法,但是有可能有问题,这就可以用abstract来强制性让子类重写父类的方法

 

抽象类一个类如果被abstract修饰那么这个类就叫抽象类。

   1.如果abstract修饰方法,那么这个方法就叫抽象的方法

   2.如果abstract修饰类,那么这个类叫抽象类。

 

方法体方法中大括号的内容就是方法体

abstract class Graphies {

         int c;
         int k;
         abstract public void area();
}
//圆形类 class Roundness extends Graphies { int r; final static double PI = 3.14; //常量的命名规则:首字母大写,多个单词用下划线隔开 public void area() { //必须重写父类的抽象方法,而且方法名、返回值类型必须相同 System.out.println("这个圆的面积是:" + PI * r * r); } public Roundness(int r) { //PI = 3.14; //如果final修饰的变量加了static修饰,则初始化变量只能在命名的就给它赋值 this.r = r; } } class Demo { public static void main(String[] args) { //创建圆形类调用方法 Roundness r1 = new Roundness(10); r1.area(); } }

 

 1.abstract关键字的使用:

         1. abstract 来修饰的方法不能有方法体。

        2.类中有抽象方法,类必须用abstract 来修饰

        3.非抽象的类,继承了这个抽象类,非抽象类中必                     须重写父类所有的抽象方法

        4.抽象类中可以有非抽象的方法,也可以没有

        5.抽象类中可以存在构造方法。-->作用是让子类能               够初始化父类中的变量和方法。

        6.抽象类不能够创建对象

           原因:如果创建对象,对象就可以调用到抽象方法,但是调用的抽象方法没有意义。

 

 

  2.abstract关键字的使用场景:

         在描述一个事物的时候,发现这个事物确实存在某种行为,但是这种行为又不具体,声明一个没有实现的行为,这种行为就叫抽象的行为

 

3.充abstract不能够和那些关键字连用:

         1.不能和private

         2.不能和static使用。

         3.不能和final使用

 

四.接口

Java中很常见

1.接口定义模式:

     interface关键字来表示接口

     结构:interface 接口名();

     结构:

       class implements 接口名1,接口名2...{

       }

 

一个类如果实现了一个接口,需要将所有的抽象方法实现

2.作用:

1.    用来扩展功能

2.    让程序解耦

3.    定义约束

 

// 要继承的类1  用interface关键字
interface Pin
{       
         int age = 12;   //默认是由final修饰的,必须给它赋值。而且只能赋值一次
         public void xie(); //默认是由abstract修饰的 
}


interface Ca  // 要继承的类2  用interface关键字
{
         public void ca();
}

//继承类 用implements关键字
class PinCa implements Pin, Ca   //注意继承多个接口的方法,要用逗号隔开
{
         public void xie() {
                   System.out.println("写字的功能");
         }

         public void ca() {
                   System.out.println("擦字的功能");
         }
}

class Demo
{
         public static void main(String[] args)
         {
                   PinCa pc =new PinCa();
                   pc.xie();
                   pc.ca();
         }
}

3.接口的使用注意事项:

          1.接口是一个特殊的类,是可以定义属性和方法。

          2.成员变量默认是用final修饰的  public static final 实际上是一个常量,必须初始化一次而且只能初始化一次

          3.方法都是抽象的 abstract public

          4.接口中不能有创建对象、构造方法和普通方法,因为默认是由abstract修饰的类,方法中不能带有方法体的,不带主体的普通方法、构造方法是没有意义的,所有不能使用。

          5.接口是给类去实现的,非抽象类实现接口时,必须把接口中的所有方法都实现了。

 

 

posted @ 2016-11-22 07:54  夏小天&  阅读(338)  评论(0编辑  收藏  举报