public class 子类(派生类) extends 父类(基类){ } 1、子类会继承父类的属性和方法,私有属性和方法不能直接使用。 2、请注意:Java中的类的继承是单继承!!!(一个子类只能继承一个父类,不能继承多个父类,这一点与C++不同) 3、子类继承父类后,到底可以调用父类中的哪些属性和方法,具体要看前面的修饰符。 下面补充修饰符的相关知识: 共有的,以public 修饰符指定,对所有类可见。 受保护的,以 protected 修饰符指定,对同一包内的类和所有子类可见。 默认的,也称为 default,在同一包内可见,不使用任何修饰符(No Keyword)。 私有的,以 private 修饰符指定,在同一类内可见。 总结: 对于同包继承,可以调用public、protected、default。 对于跨包继承,可以调用public、protected。
方法重写的条件: 1.必须要有继承关系; 2.子类重写的方法中的具体实现要和父类的不同; 3.子类在重写方法时,子类方法的返回值数据类型,方法名和参数都必须要和父类的完全一致; 4.子类在重写方法时,子类方法的访问修饰符可以大于或者等于父类方法的访问修饰符。(public>protected>default>private) 不是所有方法都可以重写,有哪些方法不能重写呢? 不能重写的方法有下面几种: 1.构造方法不能重写; 2.final修饰的方法不能重写,如果重写会报错; 3.private修饰的方法不能重写,如果写了叫做定义新方法; 4.默认修饰的方法在特定情况下也不能重写,如果写了叫做定义新方法. 如何调用重写之后的方法呢? 根据new关键字后面的类名来决定,如果类名是子类的,则优先执行子类的方法,如果子类没有才会执行父类的方法。
例如: UNStudnet类是Student的一个子类,study()是一个重写的方法,则: Student stu=new UNStudnet(); un.study()是调用UNStudent中重写的study()的方法,但若子类没有此方法,就会执行父类中study()方法。
但是如果想子类和父类中的方法都执行,应该如何操作呢? 这时候就可以用super()关键字来调用父类中的方法。
例如: 子类Student类中的定义study方法: public void study() { System.out.println(“学生正在学习中”); }
父类UNStudent类中重写的study()方法: public void study() { System.out.println(“大学生正在学习中”); }
实例化一个Student对象: Student stu=new UNStudnet();
如果直接stu.study(),则输出“大学生正在学习中”,但是如果 父类UNStudent类中重写的study()方法是: public void study() { super.study(); System.out.println(“大学生正在学习中”); }
再次调用stu.study(),则输出结果是“学生正在学习中”和“大学生正在学习中”这两条信息。
//父类中的部分代码 public class Image { public void gongji(Image i1) { i1.hp=i1.hp-shanghai; System.out.println(name+"攻击了"+i1.getname()+","+i1.getname()+"血量降低了"+shanghai+",当前血量为"+i1.gethp()); if(i1.gethp()<=0) { i1.setcunhuo(0); System.out.println(i1.getname()+"死亡"+name+"胜利"); } } } //子类重写部分的代码 public class boss extends Image { public void gongji(Image i1) { i1.downhp(getshanghai()); i1.downhp(getshanghai()); System.out.println(getname()+"攻击了"+i1.getname()+"两次,"+i1.getname()+"血量降低了"+2*getshanghai()+","+i1.getname()+"当前血量为"+i1.gethp()); if(i1.gethp()<=0) { i1.setcunhuo(0); System.out.println(i1.getname()+"死亡"+getname()+"胜利"); } } }转型针对的是子类和父类之间的转型。 分为自动转型(向上转型)和强制转型(向下转型)
自动转型有两周格式: 1、父类名 对象名 = new 子类名(); 2、修饰符+返回值类型+函数名+(父类名) { } 当运行该函数时,括号内放成子类也会向上转型。 也就是说创建了一个子类对象(new后面是谁的类名就是谁的对象),然后将他强制转型为父类对象。
public class Student { private String name; public void setname(String s) { name=s; } public String getname() { return name; } public void study() { System.out.println(name+"学生在学习"); } } public class UNStudent extends Student { public void study() { System.out.println(getname()+"大学生在学习"); } public void play() { System.out.println(getname()+"在玩耍"); } } public class Main { public static void main(String args[]) { Student un=new UNStudent(); un.setname("李俊哲"); un.study(); un.play(); } }以该代码为例,你会发现当你向上转型时,重写的方法依然会调用子类中的,但是子类定义的特有的方法缺丧失掉了。
1.正确的向下转型 (先向上转型再向下转型)
Fruit a=new Apple(); //向上转型 a.myName(); Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的) aa.myName(); aa.myMore();向下转型后因为都是指向子类对象,调用的当然全是子类的方法~~
2.不安全的向下转型
Fruit f=new Fruit(); Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错 aaa.myName(); aaa.myMore();f是父类对象,子类的实例aaa肯定不能指向父类f啊~~~
