Java基础--封装、继承、多态、抽象、接口
一、封装
封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。
1 /* 2 * 封装演示 3 */ 4 public class Dog { 5 // 私有化属性 6 private String name; 7 private String sex; 8 private String color; 9 10 // 封装字段 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public String getSex() { 20 return sex; 21 } 22 23 public void setSex(String sex) { 24 this.sex = sex; 25 } 26 27 public String getColor() { 28 return color; 29 } 30 31 public void setColor(String color) { 32 this.color = color; 33 } 34 35 }
二、继承
继承:是 java 中实现代码重用的重要手段之一.java中只支持单继承,即每个类只能有一个父类.继承表达的是 is a 的关系,或者说是一种特殊和一般的关系.
在java中,所有的java类都直接或间的接的继承了java.lang.long.Object类.Object类是所有java类的祖先.在定义一个类时,没有使用 extends 关键字,那么这个类直接继承Object类.
在java中,子类可以从父类中继承的有:
继承 public 和 protected 修饰的属性和方法,不管子类和父类是否在同一个包里.
继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里.
子类无法继承父类的有:
无法继承 private 修饰的属性和方法
无法继承父类的构造方法
继承条件下构造方法调用规则如下
如果子类的构造方法中没有通过super显示调用父类的有参构造方法,也没有通过this显示调用自身的其他构造方法,则系统会默认先调用父类的无参构造 方法.在这种情况下写不写super()语句效果都是一样.
如果子类的构造方法中通过super显示调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法.
如果子类的构造方法中通过this显示调用自身的其他构造方法,在相应 构造方法中应用以上两条规则.
特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止.
abstract和final是功能相反的两个关键字,abstract可以用来修饰类和方法,不能用来修饰属性和构造方法.final可以用来修饰类,方法和属性,不能修饰构造方法.
三、多态
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
多态前提:
要有继承关系
要有方法重写
要有父类引用指向子类对象
多态中的成员变量:
编译看左边(父类)、运行看左边(父类)
多态中的成员方法:
编译看左边(父类)、运行看右边(子类)
但是前提是父类和子类中都有相同的方法名,才有编译的时候看父类的方法名,运行的时候执行子类的方法名
四、抽象
使用了关键词abstract声明的类叫作"抽象类"。
class Demo1_Abstract { public static void main(String[] args) { //Animal a = new Animal(); //错误: Animal是抽象的; 无法实例化 Animal a = new Cat(); //父类引用指向子类对象 a.eat(); } } /* * B:抽象类特点 * a:抽象类和抽象方法必须用abstract关键字修饰 * abstract class 类名 {} * public abstract void eat(); * b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口 * c:抽象类不能实例化那么,抽象类如何实例化呢? * 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。 * d:抽象类的子类 * 要么是抽象类 * 要么重写抽象类中的所有抽象方法 */ abstract class Animal { //抽象类 public abstract void eat(); //抽象方法 public Animal() { System.out.println("父类空参构造"); } } class Cat extends Animal { public Cat() { super(); } public void eat() { System.out.println("猫吃鱼"); } }
问题1:
一个抽象类若没有抽象方法,可不可以定义为抽象类?若可以,有什么意义?
可以。这么做的目的就是不让其他类创建本类对象,交给子类完成
问题2:
abstract不能和哪些关键字共存?
1、abstract和static
被abstract修饰的方法没有方法体,被static修饰的可以用类名。 调用,但是类名。调用抽象方法是没有意义的。
2、abstract和final
被abstract修饰的方法强制子类重写,被final修饰的不让子类重写,所以他俩是矛盾的。
3、abstract和private
被abstract修饰的是为了让子类看到并强制重写,被private修饰的不让子类访问。
五、接口
接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合。接口通常以interface来声明。
class Demo1_Interface { public static void main(String[] args) { //Inter i = new Inter(); //接口不能被实例化,因为调用抽象方法没有意义 Inter i = new Demo(); //父类引用指向子类对象 i.print(); } } /* * A:接口概述 * 从狭义的角度讲就是指java中的interface * 从广义的角度讲对外提供规则的都是接口 * B:接口特点 * a:接口用关键字interface表示 * interface 接口名 {} * b:类实现接口用implements表示 * class 类名 implements 接口名 {} * c:接口不能实例化 * 那么,接口如何实例化呢? * 按照多态的方式来实例化。 * d:接口的子类 * a:可以是抽象类。但是意义不大。 * b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案) * C:案例演示 * 接口特点 */ interface Inter { public abstract void print(); //接口中的方法都是抽象的 } class Demo implements Inter { public void print() { System.out.println("print"); } }
接口成员特点
成员变量:只能是常量,并且是静态的并公共的。默认修饰符:public static final,建议自己手动给出
构造方法:接口没有构造方法
成员方法:只能是抽象方法。默认修饰符:public abstract
接口的使用原则如下:
(1)接口必须要有子类,但此时一个子类可以使用implements关键字实现多个接口;
(2)接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法;
(3)接口的对象可以利用子类对象的向上转型进行实例化。
package com.wz.interfacedemo; interface A{//定义一个接口A public static final String MSG = "hello";//全局常量 public abstract void print();//抽象方法 } interface B{//定义一个接口B public abstract void get(); } class X implements A,B{//X类实现了A和B两个接口 @Override public void print() { System.out.println("接口A的抽象方法print()"); } @Override public void get() { System.out.println("接口B的抽象方法get()"); } } public class TestDemo { public static void main(String[] args){ X x = new X();//实例化子类对象 A a = x;//向上转型 B b = x;//向上转型 a.print(); b.get(); } }
对于子类而言,除了实现接口外,还可以继承抽象类。
interface A{//定义一个接口A public static final String MSG = "hello";//全局常量 public abstract void print();//抽象方法 } interface B{//定义一个接口B public abstract void get(); } abstract class C{//定义一个抽象类C public abstract void change(); } class X extends C implements A,B{//X类继承C类,并实现了A和B两个接口 @Override public void print() { System.out.println("接口A的抽象方法print()"); } @Override public void get() { System.out.println("接口B的抽象方法get()"); } @Override public void change() { System.out.println("抽象类C的抽象方法change()"); } }
在Java中,一个抽象类只能继承一个抽象类,但一个接口却可以使用extends关键字同时继承多个接口(但接口不能继承抽象类)。
interface A{ public void funA(); } interface B{ public void funB(); } //C接口同时继承了A和B两个接口 interface C extends A,B{//使用的是extends public void funC(); } class X implements C{ @Override public void funA() { } @Override public void funB() { } @Override public void funC() { } }