java中的继承
1、类的继承描述的是类与类之间的关系
继承关系--通过已有的类,创建出新类的机制
2、继承是面向对象的一个重要特征【封装 继承 多态】
已有的类我们叫父类【超类】
创建出来的新类我们叫子类
3、如何完成一个继承关系?
通过extends关键字完成一个继承关系
具体格式:
访问修饰符 class 子类类名 extends 父类类名{
}
例如:
package com.click369.test.demo1;
public class Person {
}
package com.click369.test.demo1;
/**
* Student类是子类
* Person类是父类
* @author Administrator
*/
public class Student extends Person{
}
4.java中只支持单继承【一个类只能由一个父类】
例如:
public class Student extends Person , MyClass{ 错误
public class Student extends Person extends MyClass{ 错误
5.充当父类的java类绝对不能用final关键字修饰【被final关键字修饰的类是没有子类的】
例如:
public final class Person {
}
public class Student extends Person { 错误
}
6.所有类都有一个共同的父类,这个父类就是java.lang.Object类,不管是我们自己定义的java类,还是jdk提供的java类,他们都继承过java.lang.Object类,只是在书写的时候没有显示写出而已。【一切皆对象】
7.有继承关系的子类对象的构造过程
我们在创建子类的对象时,调用子类的构造方法,在通过子类的构造方法创建子类对象的时候,会默认先调用父类的无参数构造方法。
例如:
package com.click369.test.demo1;
public class Person {
public Person(){
System.out.println("Person类的构造方法");
}
public Person(int num){
System.out.println("Person类的有参数构造方法num=="+num);
}
}
package com.click369.test.demo1;
/**
* Student类是子类
* Person类是父类
* @author Administrator
*/
public class Student extends Person {
/*
* 因为通过子类的构造方法创建子类对象的时候默认会先调用父类无参数构造方法,所以super()可以被省略
public Student(){
System.out.println("Student类的构造方法");
}
*/
public Student(){
super(); //调用父类无参数构造方法
System.out.println("Student类的构造方法");
}
}
如果现在我们在通过子类的构造方法创建子类对象的时候,需要先调用父类的有参数数构造方法,如果处理?
在子类的构造方法中通过给super传递对应的参数,就可以调用父类的有参数数构造方法。
例如:
package com.click369.test.demo1;
public class Person {
public Person(){
System.out.println("Person类的构造方法");
}
public Person(int num){
System.out.println("Person类的有参数构造方法num=="+num);
}
}
package com.click369.test.demo1;
/**
* Student类是子类
* Person类是父类
* @author Administrator
*/
public class Student extends Person {
public Student(){
super(100); //调用父类有参数构造方法
System.out.println("Student类的构造方法");
}
}
8.Java中的包
为什么要有java包?
因为让我们在编写java程序的时候,会创建出很多的java类,我们在创建这些java类的时候,避免不了会创建出类名同的java类。为了区分这些个名称相同的java类,所以我们才使用包这个概念,将名字相同的java类,放置在不同包中,就可以区分出类名同的java类,只需要查看的所隶属的包名就可以区分。
在java中如何创建一个包?
通过package关键字来定义自己的程序包。
具体格式:
package 包名称;
定义包的位置:java类的首行
包名称的定义原则:
- 可以是一个合法的标识符
- 多个合法的标识符通过”.”区分
- 包名中的合法标识符不要有大写字母
- 不要有中文
具体规范:公司域名倒置 + 工程名称【项目名称】{简写} + 作用
例如:com.click369.psm.tools
com.click369.psm.helper
com.click369.psm.db
在使用这个中的java类的时候需要导入这个程序包,如果没有导入那么就无法使用这个java类。
通过import关键字来导入程序包
java.lang包是不需要用import关键字来导入,系统会自动将java.lang中的类导入。
例如:
package com.click369.psm.tools;
import com.click369.psm.helper.MyHelper;
public class TestMain {
public static void main(String[] args) {
MyHelper h=new MyHelper();
h.method();
System.out.println("java.lang自动导入");
}
}
通常我们通过import 包名+具体类的类名 【推荐】
import com.click369.psm.helper.MyHelper; //将指定包中的具体类导入
我们为省事也有能import 包名.*;
import com.click369.psm.helper.*; //将这个包中的所有类全部导入
同一个包中的类在相互访问使用的时候,是不需要导包。
9.java中的修饰符
修饰符---访问限制修饰符【限制java中的元素是否可以被访问】
因为有时候我们在程序中构造的元素中保存的数据,可能不需要被别人知道。【女人的年龄】
Java中的访问限制修饰符 : public【公共的】protected 【受保护的】没有修饰符 【缺省的】private 【私有的】
1 public【公共的】-- 可以修饰类, 变量 ,方法 ,数组
2.protected 【受保护的】---- 可以修饰变量 ,方法 ,数组
3.缺省的---- 可以修饰类, 变量 ,方法 ,数组
4.private【私有】-- 可以修饰变量 ,方法 ,数组
1.出现在类/接口上的修饰符【public/缺省的】
public修饰的类 --- 任何地方都可以使用
缺省的 修饰的类 --- 只能在同一个包中可以使用,跨包作废。
2.出现在变量 ,方法 ,数组上的修饰符,4种修饰符都可以使用
参考下面的图
1.在同一个类中任何访问修饰符修饰的变量,方法,数组,都可以被访问【忽略访问修饰符的存在】
2.同一个包中的非子类,私有修饰符【private】修饰的变量,方法,数组不能被访问,其他皆可以被访问
3.同一个包中的子类,私有修饰符【private】修饰的变量,方法,数组不能被访问,其他皆可以被访问
4.不同包中的子类,私有的【private】/缺省的修饰符修饰的变量,方法,数组不能访问,public、protected修饰符修饰的变量,方法,数组可以访问
5.不同包中的非子类,只有public修饰符修饰的变量,方法, 数组可以访问,其他的不能访问
10.子类的继承性【子类可以从父类中继承到哪些变量和方法】
1.子类中的元素【变量和方法】,由两部分组成,第一部分是子类自己定义创建的变量和方法;第二部分是从父类中继承到的变量和方法。
2.在同一个包中,子类可以继承来自父类的非private修饰符修饰的变量/方法。
例如:
package com.click369.test.demo1;
public class Person {
public String public_str="public_string";
protected String protected_str="protected_string";
String str="缺省的_string";
private String private_str="private_string";
}
package com.click369.test.demo1;
public class Student extends Person{
public void publicMethod(){
//this---本类对象【Student类的对象】{Student类是Person类的子类}
//我们并没有在Student类中定义/创建public_str,protected_str,str变量
//为什么在没有定义创建情况下却可以用this来访问public_str,protected_str,str变量?
//能够用this来访问public_str,protected_str,str变量.说明public_str,protected_str,str变量是Student类的。
//通过this来访问public_str,protected_str,str变量来自何处?
//Student类中的public_str,protected_str,str变量,看似没有定义/创建,但是他们是来自于父类Person类。
System.out.println("public_str=="+this.public_str);
System.out.println("protected_str=="+this.protected_str);
System.out.println("str=="+this.str);
//System.out.println("private_str=="+this.private_str);访问不到
}
3.在不同包中的子类,子类可以继承来自父类的public / protectedx修饰符修饰的变量/方法.
例如:
package com.click369.test.demo1;
public class Person {
public String public_str="public_string";
protected String protected_str="protected_string";
String str="缺省的_string";
private String private_str="private_string";
}
package com.click369.test.demo2;
import com.click369.test.demo1.Person;
public class SunClass extends Person{
public void publicMethod(){
//this---本类对象【SunClass类的对象】{SSunClass类是Person类的子类}
//我们并没有在SunClass类中定义/创建public_str,protected_strr变量
//为什么在没有定义创建情况下却可以用this来访问public_str,protected_str变量?
//能够用this来访问public_str,protected_str变量.说明public_str,protected_str变量是SunClass类的。
//通过this来访问public_str,protected_str,str变量来自何处?
//SunClass类中的public_str,protected_str变量,看似没有定义/创建,但是他们是来自于父类Person类。
System.out.println("public_str=="+this.public_str);
System.out.println("protected_str=="+this.protected_str);
//System.out.println("str=="+this.str); 访问不到
//System.out.println("private_str=="+this.private_str); 访问不到
}
11.成员变量的隐藏
1.在同一个类中局部变量的名称和成员变量的名称相同
如果需要强制使用被隐藏的成员变量值需要使用this访问
2.子类中的某一个成员变量的名称与父类中的某一个成员变量的名称相同。
如果需要强制使用被子类隐藏的成员变量的是需要使用super访问
例如:
public class Person {
public String personname="zhangsan";
}
package com.click369.test.demo1;
public class Student extends Person{
public char personname='你';
public void method(){
System.out.println("personname=="+personname); //你
// 如果需要强制使用被子类隐藏的成员变量的是需要使用super访问
System.out.println("personname=="+super.personname); //zhangsan
}
}
12.方法的重写
在子类中有一个方法,与父类中的某一个方法【可以被继承】一样,我们就可以认为,子类中的这个方法把父类中的方法重写---方法的重写
如果在调用子类重写之后的方法时,需要使用被子类继承来的父类的方法,在子类重写之后的方法中用super调用父类的方法.
例如:
package com.click369.test.demo1;
public class Person {
public void testMethod(){
System.out.println("Person类的实例方法");
}
}
package com.click369.test.demo1;
public class Student extends Person{
public void testMethod(){
System.out.println("Student类的实例方法--重写了父类继承的方法");
super.testMethod();
}
}
13.super关键字
1.通常出现在子类中,用于访问父类中的元素
2.super关键字表示父类对象
3.在子类的构造方法中,可以通过super关键字调用父类的构造方法执行
super()----访问父无参数的构造方法
super(参数)---访问父类有参数的构造方法
4.在子类中访问父类的成员变量 super.成员变量
5.在子类中访问父类的实例方法 super.实例方法
14.final关键字 【最终的,最后的】
1.被final修饰符修饰的类是没有子类。
2.被final修饰符修饰的方法不能被重写。
例如:
package com.click369.test.demo1;
public class Person {
public final void testMethod(){
System.out.println("Person类的实例方法");
}
package com.click369.test.demo1;
public class Student extends Person{
/* 错误
* testMethod在父类中使用final修饰符修饰了
* 被final修饰符修饰的方法不能被重写
public void testMethod(){
System.out.println("Student类的实例方法--重写了父类继承的方法");
}
*/
}
3.被final修饰符修饰的变量不能被重新赋值【常量】
例如:
public class TestMain {
public static void main(String[] args) {
final int a=100;
// a=200; 错误
}
}
15.上转型对象
子类的对象赋值给父类的变量--父类的变量中保存的是子类的对象---子类对象向上转型成父类的对象
1.上转型对象只能访问被子类可以继承的元素,子类自己的元素上转型对象是不能访问的。
如果一定要用上转型对象去访问子类自己的元素,那么就需要将这个上转型对象强制类型转换成子类对象方可访问。
例如:
package com.click369.test.demo1;
public class Person {
public String personname="zhangsan";
private String testvalue="lisi";
public void testMethod(){
System.out.println("Person类的实例方法");
}
}
package com.click369.test.demo1;
public class Student extends Person{
public String stuname="java"; //子类自己的变量
//子类自己的方法
public void testStudent(){
System.out.println("Student类的实例方法");
}
//personname变量/testMethod() -- 子类从父类继承来的
}
package com.click369.test.demo1;
public class TestMain {
public static void main(String[] args) {
//上转型对象----子类的对象赋值给父类的变量
//per---上转型对象
Person per = new Student();
//上转型对象只能访问被子类可以继承的元素
System.out.println("personname==="+per.personname);
per.testMethod();
//子类自己的元素上转型对象是不能访问的
// System.out.println("stuname==="+per.stuname);
//per.testStudent();
//如果一定要用上转型对象去访问子类自己的元素,
//那么就需要将这个上转型对象强制类型转换成子类对象方可访问。
Student stu= (Student)per;
System.out.println("stuname==="+stu.stuname);
stu.testStudent();
}
}
2.当一个方法的参数是父类类型的时候:
1.在调用方这个方法的时候,我们可以传递父类对象作为参数
2.在调用方这个方法的时候,我们可以传递父类的子类对象作为参数
3.在调用方这个方法的时候,我们可以传递上转型对象作为参数
例如:
package com.click369.test.demo1;
public class MyClass {
public void testMyClass(Person person){
System.out.println("MyClass类的实例方法");
}
}
package com.click369.test.demo1;
public class TestMain {
public static void main(String[] args) {
MyClass mc=new MyClass();
//1、在调用方这个方法的时候,我们可以传递父类对象作为参数
// Person person=new Person();
//mc.testMyClass(person);
//2.在调用方这个方法的时候,我们可以传递父类的子类对象作为参数
//Student student=new Student();
//mc.testMyClass(student);
//3、在调用方这个方法的时候,我们可以传递上转型对象作为参数
Person per11= new Student();
mc.testMyClass(per11);
}
}