Educoder-Java程序开发基础-封装、继承和多态的综合练习第1关:封装、继承和多态进阶(⼀)
package case1;
import java.util.Scanner;
public class Task1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String dogName = sc.next(); //输⼊各属性
String dogSex = sc.next();
String dogColor = sc.next();
String catName = sc.next();
String catSex = sc.next();
double catWeight = sc.nextDouble();
// 通过有参构造函数实例化Dog类对象dog
// dog调⽤talk()⽅法
// dog调⽤eat()⽅法
/********* begin *********/
Dog dog = new Dog(dogName,dogSex,dogColor);
dog.talk();
dog.eat();
/********* end *********/
// 通过有参构造函数实例化Cat类对象cat
// cat调⽤talk()⽅法
/
/ cat调⽤eat()⽅法
/********* begin *********/
Cat cat=new Cat(catName,catSex,catWeight);
cat.talk();
cat.eat();
/********* end *********/
}
}
// 抽象类Pet 封装属性name和sex
// 构造函数初始化name和sex
// 声明抽象⽅法talk()
/
/ 声明抽象⽅法eat()
abstract class Pet {
/********* begin *********/
private String name; //封装属性⽤private
private String sex;
public Pet(String name,String sex){
this.name=name;
this.sex=sex;
}
abstract void talk();
abstract void eat();
public String getName(){ //⽤get⽅法获取属性
return name;
}
public String getSex(){
return sex;
}
/********* end *********/
}
// Dog类继承⾃Pet类封装属性color
// 构造函数初始化name、sex和color
// 实现⾃⼰的talk()⽅法和eat()⽅法
/
/ talk()输出'名称:name,性别:sex,颜⾊:color,汪汪叫'
// eat()输出'name吃⾻头'
class Dog extends Pet {
/********* begin *********/
private String color;
public Dog(String name,String sex,String color){
super(name,sex); //⽤super初始化属性
}
public void talk(){
System.out.println("名称:"+Name()+",性别:"+Sex()+",颜⾊:"+color+",汪汪叫");
} //super.⽅法名获取属性
public void eat(){
System.out.Name()+"吃⾻头!");
}
/********* end *********/
}
// Cat类继承⾃Pet类封装属性weight
// 构造函数初始化name、sex和weight
// 实现⾃⼰的talk()⽅法和eat()⽅法
// talk()输出'名称:name,性别:sex,体重:weight kg,喵喵叫'
// eat()输出'name吃鱼'
class Cat extends Pet {
/********* begin *********/
private double weight;
public Cat(String name,String sex,double weight){
super(name,sex);
this.weight=weight;
}
public void talk(){
System.out.println("名称:"+Name()+",性别:"+Sex()+",体重:"+weight+"kg,喵喵叫");
}
public void eat(){
System.out.Name()+"吃鱼!");
}
/********* end *********/
}
第2关:封装、继承和多态进阶(⼆)
相关知识
为了完成本关任务,你需要掌握:1.重写和重载;2.abstract(抽象类)和interface(接⼝);3.final关键字;4.static关键字;5.多态。
重写和重载
⽅法重载(overload):
必须是同⼀个类;
⽅法名(也可以叫函数)⼀样;
参数类型不⼀样或参数数量或顺序不⼀样;
不能通过返回值来判断重载。
⽅法的重写(override)⼦类重写了⽗类的同名⽅法,两同两⼩⼀⼤原则:
⽅法名相同,参数类型相同;
⼦类返回类型是⽗类返回类型的⼦类;
⼦类抛出异常⼩于等于⽗类⽅法抛出异常;
⼦类访问权限⼤于等于⽗类⽅法访问权限。
在重写中,运⽤的是动态单分配,根据new的类型确定对象,从⽽确定调⽤的⽅法;
在重载中,运⽤的是静态多分配,根据静态类型确定对象,不能根据new的类型确定调⽤⽅法;
多态中,Father f = new Son()。
成员变量:编译运⾏参考左边;成员函数:编译看左边,运⾏看右边;静态函数:编译运⾏看左边。
abstract(抽象类)和interface(接⼝)
抽象类
⽤abstract修饰的类表⽰抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化。
⽤abstract修饰的⽅法表⽰抽象⽅法,抽象⽅法没有⽅法体。抽象⽅法⽤来描述系统具有什么功能,但不提供具体的实现,把具体实现留给继承该类的⼦类。抽象类特点:
含有抽象⽅法的类必须声明为抽象类(不管其中是否有其他⽅法);
抽象类可以没有抽象⽅法,可以有普通⽅法;
抽象类必须被继承,抽象⽅法必须被重写(若⼦类还是抽象类,不需要重写);
抽象类不能被实例化(不能直接构造⼀个该类的对象)。
抽象⽅法特点:
在类中没有⽅法体(抽象⽅法只需声明,⽽不需实现某些功能);
抽象类中的抽象⽅法必须被实现;
如果⼀个⼦类没有实现⽗类中的抽象⽅法,则⼦类也变成了⼀个抽象类。
接⼝ interface 中的⽅法默认为public abstract (public、abstract可以省略),变量默认为public static final;类中的⽅法全部都是抽象⽅法。只有声明没有实现,在不同类中有不同的⽅法实现。
不同点:
接⼝中只能包含抽象⽅法和默认⽅法,不能为普通⽅法提供⽅法实现;抽象类中可以包含普通⽅法;
接⼝⾥不能定义静态⽅法(jdk1.8下可以定义static⽅法),抽象类可以定义静态⽅法;
接⼝中只能定义静态常量,不能定义普通成员变量;抽象类即可以定义变量⼜可以定义静态常量;
接⼝中不包含构造器,抽象类⾥可以包含构造器,抽象类中的构造器并不是⽤于创建对象,⽽是让其他⼦类调⽤这些构造器来完成抽象类的初始化操作;
接⼝⾥不能包含初始化块,但抽象类可以包含;
⼀个类最多只能有⼀个⽗类,包括抽象类;但⼀个类可以直接实现多个接⼝,通过实现多个接⼝可以弥补Java单继承的不⾜。
共同点:
接⼝和抽象类都不能被实例化,都位于继承树的顶端,⽤于被其他类实现的继承;
接⼝和抽象类都可以包含抽象⽅法,实现接⼝和继承抽象类的普通⼦类都必须实现这些⽅法。
final关键字
final修饰的类,就是最终类,不能被继承。
final修饰的⽅法,就是最终⽅法,最终⽅法不能被重写。
final修饰⼀个引⽤变量时,是指引⽤变量不能变,引⽤变量所指向的对象中的内容还是可以改变的。修饰基本数据类型变量时,内容不能变。
final成员变量必须在初始化代码块或在构造器中初始化。
作⽤:
final类:如果⼀个类不需要有⼦类,类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计成final类。
final⽅法:①把⽅法锁定,防⽌任何继承类修改它的意义和实现。②⾼效,编译器在遇到调⽤final⽅法时候会转⼊内嵌机制,⼤⼤提升执⾏效率。
static关键字
static修饰的变量称为静态变量,静态变量属于整个类,⽽局部变量属于⽅法,只在该⽅法内有效。static不能修饰局部变量。static⽅法内部不能调⽤⾮静态⽅法。
静态变量只能在类主体中定义,不能在⽅法中定义;
static变量只会创建⼀份,不管创建⼏个对象,都共⽤⼀个变量。
类⽅法指被static修饰的⽅法,⽆this指针。其他的就是实例⽅法。类⽅法可以调⽤其他类的static⽅法。 类⽅法和对象⽅法的区别:
1、 类⽅法是属于整个类的,⽽实例⽅法是属于类的某个对象的。 由于类⽅法是属于整个类的,并不属于类的哪个对象,所以类⽅法的⽅法体中不能有与类的对象有关的内容。即类⽅法体有如下限制:
类⽅法中不能引⽤对象变量;
类⽅法中不能调⽤类的对象⽅法;
在类⽅法中不能使⽤super、this关键字。(this表⽰当前类的对象,由static修饰的⽅法是类直接调⽤,不需要创建对象,所以不能⽤this);
类⽅法不能被覆盖。
2、与类⽅法相⽐,对象⽅法⼏乎没有什么限制:
对象⽅法中可以引⽤对象变量,也可以引⽤类变量;
对象⽅法中可以调⽤类⽅法;
对象⽅法中可以使⽤super、this关键字。
static关键字的作⽤
为某特定数据类型或对象分配单⼀的存储空间,⽽与创建对象的个数⽆关;实现某个⽅法或属性与类⽽不是对象关联在⼀起;
静态变量属于类,在内存中只有⼀个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间。
多态
定义:不同类的对象对同⼀消息做出响应。同⼀消息可以根据发送对象的不同⽽采⽤多种不同的⾏为⽅式;
多态存在的三个必要条件:继承、重写、⽗类引⽤指向⼦类对象;
Java中多态的实现⽅式:接⼝实现,继承⽗类进⾏⽅法重写,同⼀个类中进⾏⽅法重载;
⽗类引⽤指向⼦类对象,该引⽤不能再访问⼦类新增的成员。Animal cat = new Cat()与直接new⼀个⽗类实例(Animal a = new Animal())的区别?答:当⽗类是接⼝和抽象类时,不能实例化,只能运⽤多态,向上转型。普通类中,可以在⼦类中重写⽗类中的⽅法,这样就可以访问⼦类中的重写⽅法。
package case2;
import java.util.Scanner;
public class Task2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String cName = sc.next();
String cSex = sc.next();
int cAge = sc.nextInt();
String eName = sc.next();
String eSex = sc.next();
int eAge = sc.nextInt();
// 创建测试类对象test
// 创建Person类对象person1,引⽤指向中国⼈,通过有参构造函数实例化中国⼈类对象
// 通过showEat()⽅法调⽤Chinese的eat()⽅法
// 创建Person类对象person2,引⽤指向英国⼈,通过有参构造函数实例化英国⼈类对象
// 通过showEat()⽅法调⽤English的eat()⽅法
/********* begin *********/
Person person1 = new Chinese(cName,cSex,cAge); //抽象类Person不能被实例化
showEat(person1); //showEat是静态⽅法可以调⽤
Person person2=new English(eName,eSex,eAge);
showEat(person2);
/********* end *********/
// 强制类型转换(向下转型) 调⽤Chinese类特有的⽅法shadowBoxing()
// 强制类型转换(向下转型) 调⽤English类特有的⽅法horseRiding()
/********* begin *********/
Chinese d = (Chinese) person1;
d.shadowBoxing(); //使⽤特有的⽅法就需要向下转型,因为person1属于Person类
English f =(English) person2;
f.horseRiding();
/
********* end *********/
}
// 定义showEat⽅法,使⽤⽗类作为⽅法的形参,实现多态,传⼊的是哪个具体对象就调⽤哪个对象的eat()⽅法
/********* begin *********/
public static void showEat(Person p){
p.eat();
}
/********* end *********/
}
// 抽象类Person 封装属性name、sex和age
// 构造函数初始化name、sex和age
// 声明抽象⽅法eat()
abstract class Person {
/********* begin *********/
String name;String sex;int age;
Person(String name,String sex,int age){
this.name=name;this.sex=sex;this.age=age;
}
abstract void eat();
/********* end *********/
}
// Chinese类继承⾃Person类
/
/ 构造函数初始化name、sex和age
// 重写⽗类⽅法eat() 输出'姓名:name,性别:sex,年龄:age,我是中国⼈,我喜欢吃饭!'
// 定义⼦类特有⽅法shadowBoxing(),当⽗类引⽤指向⼦类对象时⽆法调⽤该⽅法输出'name在练习太极拳!'
class Chinese extends Person {
/********* begin *********/
public Chinese(String name,String sex,int age){
super(name,sex,age);
}
/********* end *********/
@Override
void eat(){
System.out.println("姓名:"+name+",性别:"+sex+",年龄:"+age+",我是中国⼈,我喜欢吃饭!");
}
void shadowBoxing(){
System.out.println(name+"在练习太极拳!");
}
}
// English类继承⾃Person类
// 构造函数初始化name、sex和age
// 重写⽗类⽅法eat() 输出'姓名:name,性别:sex,年龄:age,我是英国⼈,我喜欢吃三明治!'
// 定义⼦类特有⽅法horseRiding(),当⽗类引⽤指向⼦类对象时⽆法调⽤该⽅法输出'name在练习骑马!'
class English extends Person {
/********* begin *********/
public English(String name,String sex,int age){
super(name,sex,age);
}
@Override
void eat(){
System.out.println("姓名:"+name+",性别:"+sex+",年龄:"+age+",我是英国⼈,我喜欢吃三明治!");
}
void horseRiding(){
System.out.println(name+"在练习骑马!");
}
/********* end *********/
}
/*知识点⽬录
1,Java继承
1.1 继承的概念
1.2 继承的特性
1.3 继承关键字
1.4 构造器
2,Java重写(Override)与重载(Overload)
2.1 重写(Override)
2.2 重载(Overload)
2.3 总结
3,Java多态
3.1 多态的实现⽅式
4,Java抽象类
5,Java封装
6,Java接⼝
*/
/* 1.1继承的概念
继承在本职上是特殊——⼀般的关系,即常说的is-a关系。⼦类继承⽗类,表明⼦类是⼀种特殊的⽗类,并且具有⽗类所不具有的⼀些属性或⽅法。通过 extends 关键字可以声明⼀个类是从另外⼀个类继承⽽来的。
*/
/* 1.2继承的特性
1).⼦类拥有⽗类⾮private的属性,⽅法;
2).⼦类可以拥有⾃⼰的属性和⽅法,即⼦类可以对⽗类进⾏扩展;
3).⼦类可以⽤⾃⼰的⽅式实现⽗类的⽅法;
4).Java的继承是单继承,这是Java继承区别于C++继承的⼀个特性;
5).提⾼了类之间的耦合性(继承的缺点,耦合度⾼就会造成代码之间的联系)。
*/
/* 1.3继承关键字
1).使⽤ extends 和 implements 来实现继承,所有的类都是继承于 java.lang.Object,当⼀个类没有继承的两个关键字,则默认继承Object;
2).⼀个⼦类只能拥有⼀个⽗类,所以 extends 只能继承⼀个类;
3).使⽤ implements 关键字变相的使Java具有多继承的特性,为类继承接⼝,可以同时继承多个接⼝;
4).通过super关键字来实现对⽗类成员的访问,⽤来引⽤当前对象的⽗类;
5).final 关键字
5.1) 声明类则把类定义为不能继承的,即最终类;修饰⽅法,则该⽅法不能被⼦类重写;定义实例变量,则变量不能被修改;
5.2) final 类的⽅法⾃动为 final⽅法,但实例变量不⾃动是 final变量。
*/
interface A{}
interface B{}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
Animal(){
System.out.println("Animal()");
}
Animal(int n){
System.out.println("Animal(int)");
}
java重写和重载的区别}
final class Dog extends Animal implements A,B {
final String name = "旺财";
final public void finalFun(){
}
/* 2.1.1 重写(Override)
1).重写是⼦类对⽗类的允许访问的⽅法的实现过程进⾏重新编写, 返回值和形参都不能改变。即外壳不变,核⼼重写;
2).重写的好处在于⼦类可以根据需要,定义特定于⾃⼰的⾏为。也就是说⼦类能够根据需要实现⽗类的⽅法;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论