所有知识点均来源于《Java从入门到精通》(第六版)。
一类继承另一个类需要用extends
关键字
class Child extends Parent{}
main()
中创建子类对象的时候,会先执行父类的构造方法,然后再执行子类的构造方法;class Telephone{
String button = "button: 0-9";
void call(){
System.out.println("开始拨打电话");
}
public Telephone(){
System.out.println("调用父类构造方法");
}
}
class Mobile extends Telephone{
String screen = "screen: 液晶屏";
public Mobile(){
System.out.println("调用子类构造方法");
}
}
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();
}
}
结果为:
调用父类构造方法
调用子类构造方法
button: 0-9
screen: 液晶屏
开始拨打电话
Java中所有的类都直接或间接的继承了java.long.object
类,object类是java的最高层,用户创建一个类的时候,除非是指定从其他类继承,否则就是从java.long.object
类继承而来。
java中的每个类都来自java.long.object
,如String类,Integer类都继承与Object类,此外,自定义的类也继承于Object类。由于所有类都是Object的子类,定义的时候会省略extends Object。
class Anything {}
等价于
class Anything extends Object {}
由于所有类都是Object的子类,任何类都可以重写Object类里的方法。
Object类中getClass(), notify(), notifyAll(), wait()等方法都不能被重写,因为这些方法被定义为final型。
会返回对象执行时的Class实例,然后用实例调用getName()方法可以取得类的名字。
getClass().getname();
会将对象返回为字符串形式,返回一个String实例,是可以被重写的。
public class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String toSting () {
return "我叫"+name+",今年"+age+"岁。";
}
public static void main(String[] args) {
MainDemo s1 = new MainDemo("张三",16);
System.out.println(s1.toSting());
MainDemo s2 = new MainDemo("李四",18);
System.out.println(s2.toSting());
}
}
结果
我叫张三,今年16岁。
我叫李四,今年18岁。
==
比较的是两个对象引用内存地址时候相同equal()
比较的是两个对象的实际内容数据类型的转换在上一篇
将子类类型的对象转换为父类类型的对象,可以把子类类型的对象直接赋值给父类类型对象,从而实现按照父类描述子类的效果。
class People()
class Teacher extends People {}
public class Demo3{
public static void main(String[] args){
People tom = new Teacher();
}
}
这里的意思是,把教师类new Teacher()
的对象赋值给人类People
变量tom
,进行了向上的转型,是安全的,当然在运用向上转型的过程中,父类的对象是没有办法运用子类独有的属性或者方法的。
是不安全的,需要用强制类转换
子类类型 子类对象 = (子类类型)父类对象;
Bird bird = new Pigeon();
Pigeon pigeon = (Pigeon) bird;
在向下转型的过程中,如果父类对象不是子类对象的实例,就会出现`ClassCasrExpectation``错误,所以要判断父类对象是否为子类对象的实例。
myobject (某类对象的引用) instanceof ExampleClass (某个类)
这里子类实例 instanceof 父类
是可以得到true的。
构造方法由类名决定,如果希望以不同的方式来实例化对象,就需要使用多个构造方法来完成。由于这些构造方法都需要用类名命名,为了让方法名相同但形参不同的构造方法同时存在,就需要方法的重载。
方法的重载就是在同一个类里允许存在一个以上的同名方法(不仅仅是构造方法),只要这些方法的参数个数或者类型不一样就行。
虽然在方法重载中可以使两个方法的返回类型不同,但是只有返回类型不同并不足以区分两个方法的重载,还需要通过参数的个数以及参数的数据类型来设置。
返回值 方法名(参数数据类型...参数名称)
其实这个参数就是个数组int....a
其实也就是int[] a
在程序运行过程中一直不会改变的量
final int number;
number = 12345;
number = 123; //会报错
方法定义为final可以防止子类修改父类的定义与实现方式,同时定义为final的方法执行效率会比非final要高。
如果一个父类的某个方法被修饰为private,子类将无法访问该方法,自然无法覆盖这个方法,所以被修饰为private的方法被隐式的指定为final类型,所以修饰为private的方法不用再写final。
final不用写
private final void test() {
}
final 类名{}
定义为final的类不能被继承也不允许别人对这个类进行任何改动,这个类里所有的方法都被隐式的设置为final方法,不过final类中的成员变量可以被定义为final或者非final的。
java.long.Math
和java.long.String
都是final类的所以
下面两种都是错的。
class MyMath extends java.long.Math {}
class MyString extends java.longString {}
多态是说写一段程序对所有类进行通用的处理,可以以不同的类对象为参数调用用一个方法,可以处理不同对象的问题,不用对所有的子类分别定义作用相同的方法。
class TrafficLights {}
class RedLight extends TrafficLights {}
class YellowLight extends TrafficLights {}
class GreenLight extends TrafficLights {}
public class Demo {
public static void lighten(TrafficLights light) {
if(light instanceof RedLight)
System.out.println("红灯亮45秒");
if(light instanceof YellowLight)
System.out.println("黄灯亮3秒");
if(light instanceof GreenLight)
System.out.println("绿灯亮30秒");
}
public static void main(String[] args) {
TrafficLights red = new RedLight();
lighten(red);
TrafficLights yellow = new YellowLight();
lighten(yellow);
TrafficLights green = new GreenLight();
lighten(green);
}
}
这里要注意,p不管是Teacher类还是Student类 instanceof People永远都是True的,所以不能再if里写p instanceof People
,写了的话就不会走别的condition了。
class People {}
class Teacher extends People {}
class Student extends People {}
public class Demo1 {
public static void work (People p) {
if (p instanceof Teacher) {
System.out.println("教师要好好授课");
} else if (p instanceof Student) {
System.out.println("学生要好好学习");
} else {
System.out.println("每个人要好好工作");
}
}
public static void main(String[] args) {
work(new People());
work(new Teacher());
work(new Student());
}
}
仅用来描述特征且极具抽象特性的类叫做抽象类,比如图形类,其实并不能给出一个准确的定义(有几条边几个角?都不知道)。
一般会讲父称为抽象类,需要用这个父类来进行继承和多态处理。
用abstract
关键字定义的类叫做抽象类,使用这个关键字定义的方法叫做抽象方法,抽象方法没有方法体,本身也没有什么意义,除非被重写,其实抽象类除了被继承其实也没有意义,而且不能在非抽象类中获取抽象方法,只有抽象类中才有抽象方法:
public abstract class Parent{
abstract void testAbstract();
}
就像上面的例子说的:
这里有一个问题是,所有的子类都必须重写抽象方法,那些其实不需要的子类也需要重写。所以如果将方法放在另一个类里,让那些需要重写的类来继承,不需要重写的类继承抽象类,也会产生另一个问题就是我们一开始的前提就是后序所说的所有类都应该继承抽象类,那那些需要重写的子类继承了方法的封装类后就没法继承一开始的抽象类了,为了应对这些问题需要用接口。
可以把接口看成是一种抽象类,接口中的所有方法都没有方法体。
定义接口的方法可以省略public
,abstract
关键字。
public interface name{
void lighten();
}
一个类继承一个父类的同时再实现一个接口,子类与父类之间是 extends 继承关系,类与接口之间是 implements 实现关系,可以写成:
public class Parallelogram extends Quadrangle implements Paintable {
}
public
或者abstract
形式,其他修饰符不被承认,如果没有声明的话,当public
看;static
和final
的;class 类名 implements 接口1,接口2,接口3
interface intf1{}
interface intf2 extends intef1{}