< 修饰符> class < 子类名称> [extends < 父类>] { <属性和方法的声明> }
子类继承了父类,就继承了父类的方法和属性。
在子类中,可使用父类中定义的方法和属性,也能够建立新的数据和方法。
于是,子类一般比父类的功能更多。
在Java中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。java
Java只支持单继承,不容许多重继承
一个子类只能有一个父类
一个父类能够派生出多个子类
子类不能继承父类中私有的(private)的成员变量和方法app
package com.uncleyong; import java.util.Date; public class Person { public String name; public int age; public Date birth; private String lover = "lucy"; public String getInfo(){ return "name: " + name + ", " + "age: " + age + ", " + "birth: " + birth+ ", " + "lover: " + lover; } }
package com.uncleyong; public class Student extends Person{ public String school; }
package com.uncleyong; import java.util.Date; public class TestPerson { public static void main(String[] args) { Student student = new Student(); student.name = "Jerry"; student.birth = new Date(); student.age = 1; student.school = "清华"; System.out.println(student.getInfo()); Person person = new Person(); person.age = 1; person.birth = new Date(); person.name = "Tom"; System.out.println(person.getInfo()); } }
能够对Java类中定义的属性和方法进行访问控制----规定不一样的保护等级: public、protected、default、privateide
在子类中能够根据须要对从父类中继承来的方法进行改造—覆盖方法(方法的重置、重写),在程序执行时,子类的方法将覆盖父类的方法。测试
覆盖方法必须和被覆盖方法具备相同的方法名称、参数列表和返回值类型。this
覆盖方法不能使用比被覆盖方法更严格的访问权限。spa
package com.uncleyong; /** * 定义一个ManKind类,包括 * 成员变量 int sex 和 int salary; * 方法 void manOrWorman():根据sex的值显示“man”(sex==1)或者“women”(sex==0); * 方法 void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。 */ public class ManKind { int sex; int salary; public void manOrWoman(){ if(sex == 0){ System.out.println("woman"); }else if(sex == 1){ System.out.println("man"); } } public void employeed(){ if(salary != 0){ System.out.println("job"); }else{ System.out.println("no job"); } } }
package com.uncleyong; /** * 定义类 Kids1 继承ManKind,并包括 * 成员变量 int yearsOld; * 方法 printAge() 打印 yearsOld 的值。 * * 在Kids1中从新定义employed() 方法,覆盖父类ManKind中定义的employed()方法, * 输出“Kids should study and no job.” */ public class Kids1 extends ManKind { int yearsOld; void printAge(){ System.out.println("yearsOld: " + yearsOld); } // 方法重写 public void employeed() { System.out.println("Kids should study and no job."); } //在Kids1类的main方法中实例化Kids1的对象 someKid,用该对象访问其父类的成员变量及方法。 public static void main(String[] args) { Kids1 someKid = new Kids1(); someKid.sex = 1; someKid.salary = 5000; someKid.yearsOld = 25; someKid.manOrWoman(); someKid.employeed(); someKid.printAge(); } }
在Java类中使用super来引用父类的成分orm
super可用于访问父类中定义的属性
super可用于调用父类中定义的成员方法
super可用于在子类构造方法中调用父类的构造方法
super的追溯不只限于直接父类对象
子类继承父类全部的成员变量和成员方法,但不继承父类的构造方法
在一个Java类中能够经过两种方式得到构造方法:
使用系统默认的无参数构造方法
显式定义一个或多个构造方法
一旦显式定义了构造方法,则系统再也不提供默认构造方法blog
在子类的构造方法中可以使用super(参数列表)语句调用父类的构造方法
若是子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法
若是子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错继承
package com.uncleyong; public class Circle { protected double radius; public Circle() { this.radius = 1; System.out.println("父类构造方法"); } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double findArea(){ return 3.14 * radius * radius; } }
package com.uncleyong; public class Cylinder extends Circle{ private double length; public Cylinder() { this.length = 1; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } /** * 返回圆柱的体积 * @return */ public double findVolume(){ return super.findArea() * length; // 这里要加super表示调父类的,不加super表示调本类中的findArea方法 } /** * 返回圆柱的表面积 */ @Override public double findArea() { return super.findArea() * 2 + 2 * 3.14 * radius * length; } }
package com.uncleyong; public class TestCylinder { public static void main(String[] args) { Cylinder cylinder = new Cylinder(); cylinder.setLength(2); //返回表面积 System.out.println(cylinder.findArea()); //返回体积 System.out.println(cylinder.findVolume()); } }
多态—在Java中,子类的对象能够替代父类的对象使用(父类类型的变量能够指向子类的对象)
一个变量只能有一种肯定的数据类型
一个引用类型变量可能指向(引用)多种不一样类型的对象
Person p = new Student(); Object o = new Person();//Object类型的变量o,指向Person类型的对象 o = new Student(); //Object类型的变量o,指向Student类型的对象
一个引用类型变量若是声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student(); m.school = “pku”; //合法,Student类有school成员变量 Person e = new Student(); e.school = “pku”; //非法,Person类没有school成员变量
属性是在编译时肯定的,编译时e为Person类型,没有school成员变量,于是编译错误。
正常的方法调用
Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo();
虚拟方法调用(多态状况下)
Person e = new Student(); e.getInfo(); //调用Student类中重写的getInfo()方法
编译时类型和运行时类型:编译时e为Person类型,而方法的调用是在运行时肯定的,因此调用的是Student类的getInfo()方法。—— 动态绑定
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,不然编译错误。
若是x属于类A的子类B,x instanceof A值也为true。
Boy b = new Boy(); System.out.println(">>>>>>>>>>>>>>>>"); // Boy继承了Student // System.out.println(b instanceof Student); // true;若是Boy没有继承Student,报类型不兼容错误 // Boy2继承了Boy System.out.println(b instanceof Boy2); // false,由于b不是Boy2的对象 System.out.println(b instanceof Boy); // true,由于b是Boy的对象 // Boy2继承了Boy Boy2 b2 = new Boy2(); System.out.println(b2 instanceof Boy); // true,由于b2是Boy的对象
小的数据类型能够自动转换成大的数据类型
如long g=20; double d=12.0f
能够把大的数据类型强制转换(casting)成小的数据类型
如 floate f=(float)12.0 int a=(int)1200L
从子类到父类的类型转换能够自动进行
从父类到子类的类型转换必须经过造型(强制类型转换)实现
无继承关系的引用类型间的转换是非法的
在造型前可使用instanceof操做符测试一个对象的类型
package com.uncleyong; public class Person { protected String name="person"; protected int age=50; public String getInfo() { return "Name: "+ name + "\n" +"age: "+ age; } } class Student extends Person { protected String school="pku"; public String getInfo() { return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school; } } class Graduate extends Student{ public String major="IT"; public String getInfo() { return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school+"\nmajor:"+major; } }
package com.uncleyong; public class TestInstance { /* 在类中定义方法method1(Person e); 在method1中: (1)根据e的类型调用相应类的getInfo()方法。 (2)根据e的类型执行: 若是e为Person类的对象,输出:“a person”; 若是e为Student类的对象,输出 “a student” “a person ” 若是e为Graduate类的对象,输出: “a graduated student” “a student” “a person” */ public void method1(Person e){ // 多态的体现,Person类型的形参能够接收实际Person子类对象 String info = e.getInfo(); // 动态绑定 System.out.println(info); if(e instanceof Graduate){ System.out.println("a graduated student"); } if(e instanceof Student){ System.out.println("a student"); } if(e instanceof Person){ System.out.print("a person"); } System.out.println("\n"); } public static void main(String[] args) { TestInstance ti = new TestInstance(); Person p1 = new Person(); ti.method1(p1); Person p2 = new Student(); ti.method1(p2); Person p3 = new Graduate(); ti.method1(p3); } }
Object类是全部Java类的根父类
若是在类的声明中未使用extends关键字指明其父类,则默认父类为Object类
public class Person {
...
}
等价于:
public class Person extends Object {
...
}
例:
method(Object obj){…} // 能够接收任何类做为其参数
Object o=new Person;
method(o);
==:引用类型比较引用(是否指向同一个对象);
Person p1=new Person();
Person p2=new Person();
if (p1==p2){…}
基本类型比较值:
int a=5; if(a==6){…}
用"=="进行比较时,符号两边的数据类型必须一致(可自动转换的基本数据类型除外),不然编译出错;
equals()方法是Object类的方法,因为全部类都继承Object类,也就继承了equals()方法。只能比较引用类型,其做用与“==”相同,比较是否指向同一个对象。格式:obj1.equals(obj2)
特例:当用equals()方法进行比较时,对类File、String、Date及封装类(Wrapper Class)来讲,是比较类型及内容而不考虑引用的是不是同一个对象;
缘由:在这些类中覆盖了equals()方法。
toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。在进行String与其它类型数据的链接操做时,自动调用toString()方法
Date now=new Date();
System.out.println(“now=”+now); 至关于 System.out.println(“now=”+now.toString()); // now=Date@122345
能够根据须要在用户自定义类型中重写toString()方法,如String 类重写了toString()方法,返回字符串的值。
s1=“hello”;
System.out.println(s1); // 至关于System.out.println(s1.toString());
基本类型数据转换为String类型时,调用了对应封装类的 toString()方法,int a=10; System.out.println(“a=”+a);
示例
package com.uncleyong; public class GeometricObject { protected String color; protected double weight; }
package com.uncleyong; public class Circle1 extends GeometricObject{ private double radius; public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public Circle1() { this.radius = 1; this.weight = 1; this.color = "white"; } public Circle1(double radius) { this.radius = radius; this.weight = 1; this.color = "white"; } public Circle1(double radius, double weight, String color) { this.radius = radius; this.weight = weight; this.color = color; } public double findArea(){ return Math.PI * this.radius * this.radius; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if(obj == null){ return false; } if(!(obj instanceof Circle1)){ return false; } Circle1 c = (Circle1) obj; return c.getRadius() == this.radius; } @Override public String toString() { return "" + this.radius; // 写为return this.radius;不行,由于radius是double } }
package com.uncleyong; public class TestCircle1 { /** * 写一个测试类,建立两个Circle对象,判断其颜色是否相等; * 利用equals方法判断其半径是否相等; * 利用toString()方法输出其半径。 */ public static void main(String[] args) { Circle1 c1 = new Circle1(1, 2, "Black"); Circle1 c2 = new Circle1(2, 3, "Black"); Circle1 c3 = new Circle1(2, 2, "Black"); Circle1 c4 = new Circle1(2, 3, "Red"); // 比颜色 System.out.println(c1.color.equals(c2.color)); // true // 比半径 System.out.println(c1.equals(c2)); // false // 比颜色 System.out.println(c3.color.equals(c4.color)); // false // 比半径 System.out.println(c3.equals(c4)); // true System.out.println(c1); // 1.0 打印对象,会自动调对象的toString方法 } }
针对八种基本定义相应的引用类型—封装类
int i = 10; Integer j = 10; // Integer是封装类,基本数据类型10赋给j,自动装箱