类与对象(中)(继承性)

一.类的继承
类的继承是指在现有类的基础上去构建一个新的类,构建出来的新类被称作子类。现有类被称作父类或者是基类,子类也被称作派生类。子类可自动拥有父类所有可继承的属性和方法。
1.基本概念

/*
 * 类的继承中需要注意的问题:
 * 1.类只支持单继承,不允许多重继承
 * 2.多个类可以继承同一个父类
 * 3.多层继承是可以的,即一个类的父类可以再去继承另外的父类。
 * 4.子类和父类是一对相对的概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如B类是A类的子类,同时又是C类的父类。
 */
//定义Animal类
class Animal {
	String name;

	void shout() {
		System.out.println("动物发出叫声");
	}

}

//定义Dog类继承Animal类
class Dog extends Animal {
	public void printName() {
		System.out.println("name=" + name);
	}
}

public class Demo01 {
	public static void main(String[] args) {
		Dog dog = new Dog();// 创建一个Dog类的实例对象
		dog.name = "沙皮狗";// 为dog类对象的name属性进行赋值
		dog.shout();// 调用Dog类对象的printName方法
		dog.printName();// 调用Dog类继承的shout()方法
	}
}

运行结果:
在这里插入图片描述
2.重写父类方法

/*
 * 重写父类方法:
 * 在继承关系中,子类会自动继承父类中公共的方法,但有时也需要对继承的方法进行一些修改,及对父类的方法进行重写。
 * 注意:(子类重写的方法需要和父类被重写的方法具有相同的)
 * 1.方法名
 * 2参数列表
 * 3.返回值
 */
 /*
 * 在调用Dog类对象的shout()方法时,只会调用子类重写的方法,并不会调用父类的shout()方法 注意:
 * 子类重写父类方法时,不能使用比父类中被重写的方法更为严格的访问权限。如父类中方法的访问权限是public,子类重写父类方法的权限就不能是private
 */
class Animal {
	// 定义动物叫的方法
	void shout() {
		System.out.println("动物发出叫声");
	}

}

//定义Dog类继承动物类
class Dog extends Animal {
	// 定义狗叫的方法
	void shout() {
		System.out.println("狗发出叫声:汪汪~~~");
	}
}

public class Demo02 {
	public static void main(String[] args) {
		Dog dog = new Dog();// 创建Dog类的实例对象
		dog.shout();// 调用Dog类重写的shout()方法
	}
}

运行结果:
在这里插入图片描述
3.super关键字

 * super关键字:
 * 引入super关键字的原因:
 * 		当子类重写父类的方法后,子类对象将无法直接访问父类被重写的方法。
 * 因此,提供了super关键字来访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。

3.1使用super关键字调用父类的成员变量和成员方法

//定义Animal类
class Animal {
	String name = "动物";

	void shout() {
		System.out.println("动物发出叫声");
	}
}

//定义Dog类继承动物类
class Dog extends Animal {
	String name = "犬类";

	// 重写父类的shout()方法
	void shout() {
		super.shout();// 访问父类的成员方法
	}

	void printName() {
		System.out.println("name=" + super.name);// 访问父类的成员变量
	}
}

public class Demo03 {
	public static void main(String[] args) {
		Dog dog = new Dog();// 创建一个dog对象
		dog.shout();// 调用dog对象重写shout()方法
		dog.printName();// 调用dog对象的printName()方法
	}
}

运行结果:
在这里插入图片描述
3.2使用super关键字调用父类的构造方法

//定义Animal类

class Animal {
	// 定义Aniaml类有参构造方法
	public Animal(String name) {
		System.out.println("我是一只" + name);
	}
}

//定义Dog类继承Animal类
class Dog extends Animal {
	public Dog() {
		super("沙皮狗");// 调用父类有参的构造方法
	}
}

public class Demo04 {
	public static void main(String[] args) {
		Dog dog = new Dog();// 创建Dog类的实例对象
	}
}

运行结果:
在这里插入图片描述
错误用例:

//super("沙皮狗");// 调用父类有参的构造方法		将这一行注释掉
会出现报错信息:
Implicit super constructor Animal() is undefined. Must explicitly invoke another constructor
分析:
在子类的构造方法中一定会调用父类的某个构造方法,如果没有指定,在实例化子类对象时,会默认调用父类无参的构造方法,而错误用例中,父类Animal类无无参的构造方法,所以在子类默认调用父类无参构造方法时会出错。
修改:
在子类中显式地调用父类中已有的构造方法,或者在父类中定义无参的构造方法。
结论:
在定义一个类时,如果没有特殊需求,当定义了有参构造方法后,尽量在类中再显示地定义一个无参构造方法,这样可以避免该类被继承时出现错误。

4.Object类
在Java中提供了一个Object类,它是所有类的父类,即每个类都直接或者间接继承自该类,因此Object类通常被称为超类、基类或根类。当定义一个类时,如果没有使用extends关键字为这个类显式地指定父类,那么该类会默认继承Object类。

//定义Animal类
class Animal {
	// 重写Object类的toString方法
	public String toString() {
		return "这是一只动物";
	}
}

public class Demo05 {
	public static void main(String[] args) {
		Animal animal = new Animal();// 创建Animal对象
		System.out.println(animal.toString());// 打印Aniaml的toString()
	}
}

运行结果:
在这里插入图片描述
二.final关键字

特性:
1.final修饰的类不能被继承
2.final修饰的方法不能被子类重写
3.final修饰的变量(成员变量和局部变量)是常量,只能赋值一次
public class Example{
	//final修饰的成员变量,必须在声明的同时进行赋值,否则编译错误
	final int m;//报错
	public static void main(String[] args) {
		//final修饰的局部变量,可以先声明,再进行一次赋值
		final int n;
		n=4;
	}
}

三.抽象类和接口
3.1抽象类

 * ——当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式是无法确定的。
 * 针对这种情况,Java提供了抽象方法来满足这种需求。
 * 抽象方法必须使用abstract关键字来修饰,并且在定义方法时不需要实现方法体。
 * 当一个类中包含的抽象方法,那么该类也必须使用abstract关键字来修饰.
 * 这种使用abstract关键字修饰的类就是抽象类。
 * 
 * 注意:
 * 包含抽象方法的类必须定义为抽象类,但抽象类中可以不包含任何抽象方法。
 * 另外,抽象类是不可以被实例化的,因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用。
 * 如果想要调用抽象类中定义的抽象方法,需要创建一个子类,在子类中实现抽象类中的抽象方法。
//定义抽象类Animal
abstract class Animal {
	// 定义抽象方法shout()
	public abstract void shout();
}

//定义Dog类继承Animal类
class Dog extends Animal {
	// 实现抽象方法shout(),编写方法体
	public void shout() {
		System.out.println("汪汪~~~");
	}
}

public class Demo01 {
	public static void main(String[] args) {
		Dog dog = new Dog();// 创建Dog类的实例对象
		dog.shout();// 调用Dog对象的shout()方法
	}
}

运行结果:
在这里插入图片描述
3.2接口

* 接口是一种特殊的抽象类,它不能包含普通方法,其内部的所有方法都是抽象方法,它将抽象进行的更为彻底。
 * 接口中除了抽象方法外,还可以有默认方法和静态方法(也叫类方法)。
 * 默认方法使用default修饰,静态方法使用static修饰,并且这两种方法都允许有方法体。
 * 与定义类不同的是,在定义接口时,不再使用static关键字,而是使用interface关键字来声明。
 * 
 * 提示:
 * 在接口中定义常量时,可以省略“public static final”修饰符,此时,接口会默认为常量添加“public static final”修饰符。
 * 与此类似,在接口中定义抽象方法时,也可以省略“public abstract”修饰符。
 * 定义default默认方法和static静态方法时,可以省略“public”修饰符,这些修饰符系统会默认进行添加。
 * 
 * 调用格式:
 * 静态方法可以通过“接口名.方法名”的形式来调用,而抽象方法和默认方法只能通过接口实现类的实例对象来调用。
 * 一个类可以在继承另一个类的同时实现多个接口,并且多个接口之间需要使用英文,分隔。
 *
 *接口的实现类,必须实现接口中所有的抽象方法,否则程序编译报错。
//定义Aniaml接口
interface Animal {
   int ID = 1;

   void breathe();

   // 定义一个默认方法
   default void getType(String type) {
   	System.out.println("该动物属于:" + type);
   }

   // 定义一个静态方法
   static int getID() {
   	return Animal.ID;
   }
}

//Dog类实现了Aniaml接口
class Dog implements Animal {
   // 实现breathe()方法
   public void breathe() {
   	System.out.println("狗在呼吸");
   }
}

public class Demo02 {
   public static void main(String[] args) {
   	System.out.println(Animal.getID());// 通过接口名调用类方法
   	Dog dog = new Dog();// 创建Dog类的实例对象
   	System.out.println(dog.ID);// 在实现类中获取接口全局变量
   	dog.breathe();// 调用dog对象的breathe()方法
   	dog.getType("犬科");// 通过接口实现Dog的实例化对象,调用接口默认方法
   }
}

运行结果:
在这里插入图片描述

接口和接口之间可以是继承关系,接口中的继承同样使用extends关键字来实现。
接口的特点:
1.当一个类实现接口时,如果这个类是抽象类,只需实现接口中的部分抽象方法即可,否则需要实现接口中的所有抽象方法。
2.一个类在继承一个类的同时还可以实现接口,此时,extends关键字必须位于implements关键字之前。
//定义Animal接口
interface Animal {
	int ID = 1;// 定义全局变量

	void breath();// 定义抽象方法breathe()
	// 定义一个默认方法

	default void getType(String type) {
		System.out.println("该动物属于:" + type);
	}

	// 定义一个静态方法
	static int getID() {
		return Animal.ID;
	}
}

//定义了LandAnimal接口,并继承了Aniaml接口
interface LandAnimal extends Animal {
	void run();// 定义抽象方法run()
}

class Dog implements LandAnimal {
	public void breathe() {
		System.out.println("狗在呼吸");
	}

	public void run() {
		System.out.println("狗在陆地上跑");
	}
}

public class Demo03 {
	public static void main(String[] args) {
		System.out.println(Animal.getID());// 通过接口名调用类方法
		Dog dog = new Dog();// 创建Dog类的实例对象
		System.out.println(dog.ID);// 在实现类中获取接口全局变量
		dog.breathe();// 调用Dog对象的breathe()方法
		dog.getType("犬科");// 通过Dog对象,调用接口默认方法
		dog.run();// 调用dog对象的run()方法
	}
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值