目录
1.类的继承
2.Object类
1.getClass()方法
2.toString()方法
3.equals()方法
3.对象类型的转换
1.向上转型
2.向下转型
4.使用instanceof关键字判断对象类型
5.方法的重载
6.final关键字
1.final变量
2.final方法
3.final类
7.多态
8.抽象类与接口
1.抽象类
2.接口
继承和多态是面向对象开发中非常重要的一组概念。继承和多态使用得当,整个程序的架构将变的非常有弹性,同时可以减少代码的冗余性。继承机制下,用户可以复用一些定义好的类,减少重复代码的编写。多态机制下,用户可以动态调整对象的,降低对象之间的依存关系。为了优化继承与多态,一些类除了可继承父类,还需要使用接口的形式。java中的类可以同时实现多个接口,接口被用来建立类与类之间关联的标准。正因为具有这些灵活、高效的机制,java语言才更具有生命力。
Java语言每个类只能继承一个父类
extends 继承
父类 写法与普通类写法相同 public class 父类类名(){
子类
public class 子类类名 extends 父类类名(){
所有类的构造方法第一行都有一个隐藏的“super();作用是在执行该构造方法之前调用其父类构造方法
子类重写父类的方法
返回参数相同 方法名相同 传入参数相同 只有方法体不同
继承在面对对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性。在程序中复用一些定义完整的类,不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性。
子类在继承父类之后,创建子类对象的同时也会调用符类的构造方法
1.创建之类对象,观察构造方法执行顺序
class Parent{
public Parent() {
System.out.println("调用父类构造方法");
}
}
class Child extends Parent{
public Child() {
System.out.println("调用子类构造方法");
}
}
public class Demo {
public static void main(String[] args) {
new Child();
}
}
结果如下
子类继承父类之后可以调用父类创建好的属性和方法
2.在电话类基础上衍生出手机类
class Telephone {//电话类
String button = "button:0~9";//成员属性,10个按键
void call() {//拨打电话功能
System.out.println("开始拨打电话");
}
}
class Mobile extends Telephone{//手机类继承电话类
String screen = "screen:液晶屏";//成员属性,液晶屏幕
}
public class Demo2 {
public static void main(String[] args) {
Mobile motto = new Mobile();
System.out.println(motto.button);//子类调用父类属性
System.out.println(motto.screen);//子类调用父类没有的属性
motto.call();//子类调用父类方法
}
}
结果如下
getClass()方法是Object 类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getNemo()方法可以取得类的名称。
getClass().getname();
可以将getClass方法与toString()方法联合使用。
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个string实例。在实例的应用中通常重写toSring()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的toString()方法。
3.让学生自我介绍
public class Student{
String name;
int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "我叫" + name + ", 今年" + age + "岁。";
}
public static void main(String[] args) {
Student s1 = new Student("张三",16);
System.out.println(s1);
Student s2 = new Student("李四",19);
System.out.println(s2);
}
}
结果如下
在java语言中,有两种比较对象的方式,分别为“==”运算符与equals()方法。两者的区别在于;“==”比较的是两个对象引用内存地址是否相等,而equals()方法比较的是两个对象的实际内容。
4.根据身份证号判断是否为同一人
ppublic class People {
int id;//身份证号
String name;//名字
public People(int id, String name) {
this.id = id;
this.name = name;
}
public boolean equals(Object obj) {//重写Object类的equals()方法
if(this == obj)//如果参数与本类是同一个对象
return true;
if(obj == null)//如果参数是null
return false;
if(getClass()!= obj.getClass())//如果参数与本类类型不同
return false;
People other = (People)obj;//将参数强转成本类对象
if(id!= other.id)//如果两者的身份照号
return false;
return true;
}
public String toString() {//重写Object类的toString()方法
return name;//只输出名字
}
public static void main(String[] args) {
People p1 = new People(220,"tom");
People p2 = new People(220,"汤姆");
People p3 = new People(220,"张三");
Object o = new Object();
System.out.println(p1 + "与" + p2 + "是否为同一个人?");
System.out.println("pquals()方法的结果:" + p1.equals(p2));
System.out.println("==运算符的结果:" + (p1 == p2));
System.out.println();
System.out.print(p1 + "与" + p3 + "是否为同一个人?");
System.out.println(p1.equals(p3));
System.out.print(p1 + "与" + o + "是否为同一个人?");
System.out.println(p1.equals(o));
}
}
结果如下
向上转型
子类对象赋值给父类引用 Animal a = new Dog();自动类型转换
向下转型
父类对象赋值给子类引用
Dog a =(Dog)new Animal();强制类型转换
向上转型可以被理解为将子类类型的对象转换为父类类型的对象,即把子类类型的对象直接赋值给父类类型的对象,进而实现按照父类描述子类的效果。
5.Tom是谁?
class People{}
class Teacher extends People{}
public class Demo3 {
public static void main(String[] args) {
People tom = new Teacher();
}
}
向下转型可以被理解为将父类类型的对象转换为子类类型的对象
6.谁是鸽子?
class bird{}
class Pigeon extends Bird{}
public class Dome4 {
public static void main(String[] args) {
Bird bird = new Pigeon();
Pigeon pigeon = bird;
}
}
在运行之前,Eclipse 会报出(Pigeon pigeon = bird)的编译错误,这是因为父类对象不能直接赋值给子类对象。
如果想要告诉编译器“某只鸟就是一只鸽子”,应该如何?答案就是强制类型转换。也就是说,要想实现向下转型,需要借助强制类型转换,语法如下:
子类类型 子类对象 = (子类类型)父类对象;
需将第8行代码修改为:
Pigeon pigeon = (Pigeon)bird;//通过强制类型转换,告诉编译器“某只鸟是一只鸽子”
instanceof对象名 instanceof 类名
判断对象是否属于该类或其子类
instanceof
对象名 instanceof 类名 判断对象是否属于该类或其子类
对象名 instanceof 接口名 判断对象是否属于该接口的实现类
7.分析几何图形之间的继承关系
class Quadrangle{}
class Square extends Quadrangle{}
class Circular{}
public class Demo5 {
public static void main(String[] args) {
Quadrangle q = new Quadrangle();
Square s new Square();
System.out.println(q instanceof Square);
System.out.println(s instanceof Quadrangle);
System.out.println(q instanceof Circular);
}
}
本例在运行之前,Eclipse就会报出(System.out.println(q instanceof Circular);)的编译错误。
System.out.println(q instanceof Circular);//判断正方形是否为圆形的子类
翻译如下
不兼容的条件操作数类型 四边形和圆形
因为四边形类与圆形类没有继承关系,因此两者不能使用instanceof关键字进行比较,否则会发生“不兼容”的错误,如果如果删除或注释这行代码,运行结果如下
false
true
重载
方法名相同参数不同
8.编写不同形式的加法运算方法
public class OverLoadTest {
public static int add(int a,int b) {//定义一个方法
return a + b;
}
public static double add(double a, double b) {//与第一个方法名称相同、参数类型不同
return a + b;
}
public static int add(int a) {//与第一个方法参数个数不同
return a;
}
public static int add(int a,double b) {//先int参数,后double参数
return a;//输出int参数
}
public static int add(double a, int b) {//先double参数,后int参数
return b;//输出int参数
}
public static void main(String[] args) {
System.out.println("调用add(int,int)方法:" + add(1,2));//输出
System.out.println("调用add(dounle,double)方法" + add(2.1,3.3));
System.out.println("调用add(int)方法" + add(1));
System.out.println("调用add(int,double)方法" + add(5,8.0));
System.out.println("调用add(double,int)方法" +add(5.0,8));
}
}
运行结果如下
在谈到参数个数可以确定两个方法是否具有重载关系时,会想到定义不定长参数方法。不定长的方法的语法如下:
返回值 方法名(参数数据类型...参数名称)
9.使用不定长参数重载加法运算方法
public class OverLoadTest {
public static int add(int a,int b) {//定义一个方法
return a + b;
}
public static double add(double a, double b) {//与第一个方法名称相同、参数类型不同
return a + b;
}
public static int add(int a) {//与第一个方法参数个数不同
return a;
}
public static int add(int a,double b) {//先int参数,后double参数
return a;//输出int参数
}
public static int add(double a, int b) {//先double参数,后int参数
return b;//输出int参数
}
public static int add(int...a) {//定义不定长参数方法
int s = 0;
for (int i = 0; i < a.length;i++) {//根据参数个数做循环操作
s += a[i];//将每个参数累加
}
return s;//将计算结果返回
}
public static void main(String[] args) {
System.out.println("调用add(int,int)方法:" + add(1,2));//输出
System.out.println("调用add(dounle,double)方法" + add(2.1,3.3));
System.out.println("调用add(int)方法" + add(1));
System.out.println("调用add(int,double)方法" + add(5,8.0));
System.out.println("调用add(double,int)方法" +add(5.0,8));
System.out.println("调用不定义长参数方法:" + add(1,2,3,4,5,6,7,8,9));
System.out.println("调用不定义长参数方法:" + add(1));
}
}
结果如下
final修饰变量——不能被改变(常量)
final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final定义的变量为常量。例如,在类中定义PI值,可以使用如下语句:
final double PI = 3.14
10.定义不允许被修改的常量π
public class FinalData {
static final double PI = 3.1415926;
public static void main(String[] args) {
System.out.println("圆周率的值为:" + PI);
System.out.print("半径为3的圆的周长为:" + (2 * 3 * PI));
//常试修改PI的值
PI = 3.1416927;
}
}
本例在运行之前,Eclipse就会报出(PI = 3.1416927)的编译错误,常量PI不允许被改变
final修饰方法——不能被重写
11.使用final关键字为电视机上儿童锁
class Dad {
public final turnOnTheTV() {
System.out.println("爸爸打开了电视");
}
}
class Baby extends Dad{
public final void turnOnTheTV() {
System.out.println("宝宝也要打开电视");
}
}
本例在运行之前,Eclipse就会报出(public final void turnOnTheTV())的编译错误。因为打开电视这个方法是由final修饰的,子类无法重写。所以Baby想要打开电视,就只能找爸爸来打开了。
final修饰类——不能被继承
定义为final的类不能被继承。如果希望一个类不被如何类继承,并且不允许其他人对这个类进行任何改动,可以将这个类设置为final类。final类的语法如下:
final 类名()
final class Finalclass{
}
public class FinaTest extends Finalclass{
}
本例在运行之前,Eclipse就会报出(ublic class FinaTest extends Finalclass())的编译错误,错误如下
The type FinaTest cannot subclass the final class Finalclass
翻译如下
类型 FinaTest 不能子类最终类 最终类
利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。这种将子类对象视为父类对象的做法称为“向上转型”。
12.万能的绘图方法
class Shape{}//图形类
class Square extends Shape{}//正方形类继承图形类
class Circular extends Shape{}//图形类继承图形类
public class Demo6{
public static void draw(Shape s) {//绘制方法
if(s instanceof Square) {//如果是正方形
System.out.println("绘制正方形");
}else if(s instanceof Circular) {//如果是圆形
System.out.println("绘制圆形");
}else {//如果是其他圆形
System.out.println("绘制父类图形");
}
}
public static void main(String[] args) {
draw(new Shape());
draw(new Square());
draw(new Circular());
}
}
结果如下
抽象方法
修饰符 abstract 返回参数 方法名{传入参数};
抽象类 有抽象方法的类一定是抽象类
修饰符 abstract class 类名{
}
使用abstract关键字定义的类称为抽象类,而使这个关键字定义的方法称为抽象方法
抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而重载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承没有任何意义。定义抽象类的语法如下:
public abstract class Parent{
abstract void testAbatract();//定义抽象方法
}
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法没有方法体。
接口使用interface关键字
接口 所有方法都是抽象方法修饰符 interface 接口名{
}
实现 implements
Java语言每个类可以实现多个接口修饰符 class 类名 implements 接口1,接口2,...{
}
单接口,多实现
先继承在实现
13.将绘图方法设为接口方法
interface Paintable{//可绘制接口
public void draw();//绘制抽象方法
}
class Quadrangle{//四边形类
public void doAnything() {
System.out.println("四边形提供的方法");
}
}
//平行四边形类,继承四边形类,并实现了可绘制接口
class Parallelogram extends Quadrangle implements Paintable{
public void draw() {//由于该类实现了接口,所以需要覆盖draw()方法
System.out.println("绘制平行四边形");
}
}
//正方形类,继承四边形类,并实现可绘制接口
class Square extends Quadrangle implements Paintable{
public void draw() {
System.out.println("绘制正方形");
}
}
//图形类,仅实现了可绘制接口
class Circular implements Paintable{
public void draw() {
System.out.println("绘制圆形");
}
}
public class do1{
public static void main(String[] arge) {
Square s = new Square();
s.draw();
s.doAnything();
Parallelogram p = new Parallelogram();
p.draw();
p.doAnything();
Circular c = new Circular();
c.draw();
}
}
结果如下
Dog作业
代码如下:
public class Dog {
//成员变量
private String name;
private String sex;
private String coall;
private String jiao;
//对外提供getter和setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCoall() {
return coall;
}
public void setCoall(String coall) {
this.coall = coall;
}
public String getJiao() {
return jiao;
}
public void setJiao(String jiao) {
this.jiao = jiao;
}
//成员方法
public String introduce() {
return sex+"狗"+name+"是"+coall+"色的";
}
public String bark() {
return sex+"狗"+name+"正在"+jiao+"叫";
}
//构造参数
public Dog() {
super();
}
public Dog(String name, String sex, String coall) {
super();
this.name = name;
this.sex = sex;
this.coall = coall;
}
public Dog(String name, String sex, String coall, String jiao) {
super();
this.name = name;
this.sex = sex;
this.coall = coall;
this.jiao = jiao;
}
}
public class DogTest {
public static void main(String[] args) {
//创建对象调用构造方法
Dog Dog1 = new Dog();
Dog Dog2 = new Dog("绍雨","公","绿");
String introduce = Dog2.introduce();
//输出
System.out.println(introduce);
//创建对象调用构造方法
Dog Dog3 = new Dog("赵绍雨","公","绿","呜呜呜");
String bark = Dog3.bark();
System.out.println(bark);
}
}
结果如下