目录
10.1类的继承
10.2Object类
10.3对象类型的转换
10.4使用instanceof操作符判断对象类型
10.5方法的重载
10.6多态
10.7抽象类与接口
10.1类的继承
关键字extends
1.实例化子类对象时,父类的无参构造方法被自动调用,父类有参构造方法只能被super关键字调用。可以通过super关键字调用父类的成员与方法。(禁止调用父类private方法)如果子类中定义了一个与父类 private 方法具有相同的方法名等,这只是在子类中重新定义了一个新的方法。
2.Java类虽然只能有一个直接父类, 但它可以有无限多个间接父类。如果定义一个 Java类时, 并未显式指定这个类的直接父类.。则这个类默认继承 java.lang.Object 类
使用多层继承的方法:
package Number;
import java.sql.SQLOutput;
public class Demo {
public static void main(String[] args) {
Children chiLd=new Children();
chiLd.show();
}
}
class Parent1 {
void show(){
System.out.println("我是顶层父类");
}
}
class Parent2 extends Parent1{
}
class Children extends Parent2{
}
3.覆盖方法和被覆盖方法要么都是类方法(加static), 要么都是实例方法(不加static)。
4.this 、super不能出现在 static 修饰的方法中。
5.方法重载和方法重写在英文中分别是 overload 和 override。重载主要发生在同一个类的多个同名方法之间。而重写发生在子类和父类的同名方法之间。
重构:特殊的重写,仅仅只是方法实现内容不同,其他与父类都一样。
6.父类与子类有同名实例变量。子类里定义的方法直接访问子类中定义的实例变量。在子类定义的实例方法中可以通过 super 来访问父类中被隐藏的实例变量。
具体参考文章:
构造函数:
类的继承1
类的继承访问修饰符
转自:类的继承1
package Number;
class base
{
public double size;
public String name;
public base(double size, String name)
{
this.size = size;
this.name = name;
}
}
class Sub extends base
{
public String color;
public Sub(double size, String name, String color)
{
//通过 super 调用来调用父类构造器的初始化过程
super(size, name);
this.color = color;
}
public static void main(String[] args)
{
Sub s = new Sub(5.6, "皮卡丘", "黄色");
//输出 Sub 对象的 三个实例变量
System.out.println(s.size + "--" + s.name + "--" + s.color);
}
}
7. super 调用的是其父类的构造器, 而 this 调用的是本类中重载的构造器。
因此, 使用 super 调用父类构造器也必需出现在子类构造器执行体的第一行。所以 this 调用 和 super 调用不会同时出现。
super的3中用法:调用构造方法;调用父类的属性;调用父类的方法;
package Number;
public class Pad extends Computer {
String battery="电池5000毫安";
public Pad(){ //创建构造方法
super(); //此处super调用父类的构造方法 。只能放第一句,前面不能有其他初始化方法
this.screen=super.screen; //本类screen等于父类screen
}
void start3G(){
System.out.println("打开3G网络");
}
void showPicture(){
System.out.println("平板电脑用手指点击触摸屏");
}
String sayHello(){
return super.sayHello()+"平板电脑"; //调用父类sayHello()方法
}
}
8.子类构造器调用父类构造器:
- 子类构造器执行体的第一行使用 super 显式调用父类构造器.系统将根据 super 调用里传入的实参列表调用父类对应的构造器.
- 子类构造器执行体的第一行代码使用 this 显式调用本类中重载的构造器,系统将根据 this 调用里传入的实参列表调用本类中的另一个构造器.执行本类中另一个构造器时即会调用父类构造器.
- 子类构造器执行体中既没有 super 调用, 也没有 this 调用, 系统将会在执行子类构造器之前, 隐式调用父类无参数的构造器。
9.访问继承与修饰:
子类可以重写父类的成员方法。修改子类方法修饰权限只能>=范围,不能缩小范围。
-
父类中声明为public的方法在子类中也必须为public。
-
父类中声明为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
-
父类中默认修饰符声明的方法,能够在子类中声明为private。
-
父类中声明为private的方法,不能够被继承。
10.2Object类
java中的所有类均继承自java.lang.Object类。所有类都是Object类的子类。
getClass()方法:会返回对象执行时的Class实例。
然后使用此实例调用getName()可以获取类的名称。
getClass().getName();
toString()方法:功能为将一个对象返回为字符串形式,它会返回一个String实例。
通常重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或者与字符串连接时,将自动调用重写后的toString()方法。
package Number;
import javax.naming.Name;
import java.sql.SQLOutput;
public class Demo {
public static void main(String[] args) {
Object []arr=new Object[4]; //object类是所有类的父类,所以object数组可以存放任何一个类的对象.
arr[0]=new Object();
arr[1]=new String("字符串");
arr[2]=new Integer(6);
arr[3]=new Demo();
for (Object obj:arr){
System.out.println(obj.getClass());
System.out.println(obj);
}
}
@Override //@加上overried methods进行选择
public String toString() {
return "我是Deno类";
}
}
equals()方法:“==”是比较两个对象的引用是否相等,“equals”是比较两个对象的实际内容。
参考文档:
- ==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
- ==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
- ==指引用是否相同, equals()指的是值是否相同
public class Prson {
String name;
String ID;
@Override
public boolean equals(Object obj) {
Prson p=(Prson) obj;
boolean b1=this.name.equals(p.name); //判断该方法的name(this.name)是否与对象的name(p.name)相等。
boolean b2=this.ID.equals(p.ID);
return b1&&b2;
}
}
package Number;
import javax.naming.Name;
import java.sql.SQLOutput;
public class Demo {
public static void main(String[] args) {
Prson p1=new Prson();
Prson p2=new Prson();
Prson p3=new Prson();
p1.name="小明";
p1.ID="123";
p2.name="小红";
p2.ID="123";
p3.name="小明";
p3.ID="123";
System.out.println(p1.equals(p2));
System.out.println(p1.equals(p3));
System.out.println(p2.equals(p3));
System.out.println(p1==p2);
System.out.println(p1==p3);
System.out.println(p2==p3);
}
}
10.3对象类型的转换
类的向上转型:Parents obj=new Child();
父类声明对象,子类实例化对象
类的向下转型:Parents p=new Parents(); Child c=(Child) p; (会报错)
10.4使用instanceof操作符判断对象类型
类的向上转型:Parents obj=new Child();
父类声明对象,子类实例化对象
类的向下转型:Parents p=new Parents(); Child c=(Child) p; (会报错)
向下转型之前先用instanceof判断一个对象是否属于一个类。 返回值为boolean值
(也可以判断是否一个类实现了某个接口)
格式:子类对象 instanceof 父类名称/接口名字
boolean result=child instanceof parents;
10.5方法的重载
一个类中允许存在一个以上的同名方法:方法的参数个数不同;参数类型不同;参数顺序不同。
package Number;
public class Demo1 {
public static void main(String[] args) {
System.out.println("调用(double a)方法:"+add(3));
System.out.println("调用(double a)方法:"+add(5.0));
System.out.println("调用(int a,double b)方法:"+add(3,1.2));
System.out.println("调用(double b,int a)方法:"+add(1.1,5));
}
static int add(int a){ //原方法
return a;
}
static double add(double a){ //参数类型不同
return a;
}
static int add(int a,int b){ //参数个数不同
return a+b;
}
static int add(int a,double b){ //参数类型不同
return (int)(a+b);
}
static int add(double b,int a){ //参数顺序不同
return (int)(a+b);
}
}
10.6多态
同一个变量,同一个方法,执行出不同的结果。
package Number;
import java.sql.SQLOutput;
class Animal {
void move(){
}
}
class Fish extends Animal{
void move(){
System.out.println("鱼儿会游泳");
}
}
class Egal extends Animal{
void move(){
System.out.println("老鹰会飞");
}
}
class Demo2{
public static void main(String[] args) {
Animal jack=new Fish();
jack.move();
jack=new Egal();
jack.move();
}
}
10.7抽象类与接口
10.7.1抽象类
关键字abstract
抽象方法:只需要声明不需要实现。含有抽象方法的类必须为抽象类。(没有大括号)
abstract public void teaching(); //抽象方法
继承抽象类的所有子类,必须重写覆盖掉所有抽象方法。
构造函数的调用:
原文链接:
创建一个子类的对象实例的时候,必先调用父类的无参数的构造函数(默认构造函数),假如父类有带参数的构造函数,那么系统将不会给它创建无参数的构造函数,这时,子类在实例化的时候,因为找不到父类的默认构造函数,编译器将会报错,但假如在子类的构造函数中指定用父类的带参数的构造函数的时候,或者在父类中加一个无参数的构造函数,就不会报错。
我们假设A是B的父类,B是A的子类。
1、假如程序员没有给类A没有提供构造函数,则编译器会自动提供一个默认的无参数的构造函数,假如用户提供了自己的构造函数,则编译器就不在提供默认的无参数构造函数。
2、子类B实例化时会自动调用父类A的默认构造函数,所以假如A的默认的无参数的构造函数为private,则编译器会报错,而假如A没有提供默认的无参数的构造函数,而提供了其他类型的构造函数,编译器同样会报错,因为B找不到A的默认无参数构造函数。所以,我们最好给父类A提供一个无参数的构造函数。
3、或者在B的构造函数中显示的调用父类A的有参构造函数。
原文链接:
使用 super 调用父类的构造方法
子类可以通过 super 关键字来调用一个由父类定义的构造方法,格式如下:
super(parameter-list);
其中,parameter-list 指定了父类中构造方法所需的所有参数。super() 必须是在子类构造方法的主体第一行。
package Number;
import com.sun.javafx.sg.prism.GrowableDataBuffer;
abstract public class Animal1 {
public Animal1(){
System.out.println("创建了一个动物类");
}
abstract public void eat();
public abstract void reproduce();
}
package Number;
abstract public class Bird extends Animal1 {
String feather; //羽毛
public Bird(String feather){
System.out.println("创建了一个鸟类");
this.feather=feather;
}
public void growFeather(){
System.out.println("长满"+feather+"羽毛");
}
abstract public void move();
public void reproduce(){
System.out.println("下蛋");
}
}
package Number;
public class Seagull extends Bird { //父类为有参构造函数,必须补充子类的构造方法
public Seagull(String feather) {
super(feather);
System.out.println("我是一只海鸥");
}
@Override
public void move() {
System.out.println("海鸥飞翔");
}
@Override
public void eat() {
System.out.println("海鸥吃鱼");
}
}
package Number;
public class Chicken extends Bird{
public Chicken(String feather) { //父类为有参构造函数,必须补充子类的构造方法
super(feather);
System.out.println("我是一只小鸡");
}
@Override
public void move() {
System.out.println("小鸡快跑");
}
@Override
public void eat() {
System.out.println("小鸡吃米");
}
}
package Number;
public class Demo5 {
public static void main(String[] args) {
Seagull jack=new Seagull("白色");
jack.eat();
jack.move();
jack.growFeather();
jack.reproduce();
System.out.println();
Chicken duoduo=new Chicken("黄色");
duoduo.eat();
duoduo.move();
duoduo.growFeather();
duoduo.reproduce();
}
}
10.7.2接口
关键字interface
接口中的方法都是public(默认)或者abstract。接口中的方法不需要实现。
java中类不可以多重继承,但是接口可以多重继承。(支持向上向下转型)
类多重继承接口:class A implements 接口C,接口D,接口E……
接口也可以继承接口:interface interf1 extends intf2
package Number;
public interface DrawInterface {
public void draw();
}
package Number;
public class Qua implements DrawInterface{ //四边形类
@Override
public void draw() {
System.out.println("绘制四边形");
}
}
package Number;
public class Square implements DrawInterface{
@Override
public void draw() {
System.out.println("绘制正方形");
}
}
package Number;
public class Demo9 {
public static void main(String[] args) {
DrawInterface d1=new Qua(); //接口支持向上向下转型
d1.draw();
DrawInterface d2=new Square();
d2.draw();
}
}



