网站开发免责声明,低价网站制作,云南建设项目招标公告发布网站,开发公司房屋移交物业上次带大家学习了java里面比较重要的知识点类和对象#xff0c;而且我们知道java是一门面向对象的语言#xff0c;有时一个程序里可能有很多类#xff0c;那么这么多类他们之间有什么联系吗#xff1f;今天就带大家学习一下java类之间的关系。 什么是继承#xff1a; 我们… 上次带大家学习了java里面比较重要的知识点类和对象而且我们知道java是一门面向对象的语言有时一个程序里可能有很多类那么这么多类他们之间有什么联系吗今天就带大家学习一下java类之间的关系。 什么是继承 我们在日常学习中在java程序编写时先创建类在实例化对象进一步对类进行使用然而世界上很多事物往往都不是独立的他们之间可能存在着千丝万缕的联系那么如何建立这种联系呢 举个例子创建一个狗类
//Dog类
public class Dog{String name;String sex;int age;public void bark(){System.out.println(name正在汪汪汪);}public void sleep(){System.out.println(name正在睡觉)}
}
在定义一个猫类
public class Cat{
string name;
int age;
string color;
public void sleep()
{
System.out.println(name 正在睡觉);
}
void mew(){
System.out.println(name 喵喵喵~~~);
}
} 通过这两个例子我们可以很直观的看到这两类有太多一样的地方我们如果可以把这些一样的部分抽离出来使用时直接调用它代码效率会大大加强实现了代码的复用其实这就是继承的本质。 继承 (inheritance) 机制 是面向对象程序设计使代码可以复用的最重要的手段它允许程序员在保持原有类特性 的基础上进行扩展增加新功能 这样产生新的类称 派生类 。继承呈现了面向对象程序设计的层次结构 体现了 由简单到复杂的认知过程。继承主要解决的问题是共性的抽取实现代码用 。 例如狗和猫都是动物那么我们就可以将共性的内容进行抽取然后采用继承的思想来达到共用。 概念可能不太直观这里我以上面为例重新写一段程序 public class Animal{String name;int age;public void eat(){System.out.println(name正在吃饭);}public void sleep(){System.out.println(name正在睡觉);}
}
public class Dog extends Animal{void bark(){System.out.println(name 汪汪汪~~~);}
}
public class Cat extends Animal{void mew(){System.out.println(name 喵喵喵~~~);}
} 我们将Dog类和Cat类称为子类Animal为父类。 这样的话代码就大大简化当我们再去创建动物对象时就可以直接调用这里的Animal类中的成员这里的extends是子类继承父类成员时必须使用的关键字。
子类如何访问父类的成员 子类访问父类的成员这里分为两种情况 子类成员与父类成员名字一致。子类成员与父类成员名字不一致。 子类成员与父类成员名字一致
public class Base {
int a;
int b;
int c;
}
/
public class Derived extends Base{
int a; // 与父类中成员a同名且类型相同
char b; // 与父类中成员b同名但类型不同
public void method(){
a 100; // 访问父类继承的a还是子类自己新增的a
b 101; // 访问父类继承的b还是子类自己新增的b?
c 102; // 子类没有c访问的肯定是从父类继承下来的c
// d 103; // 编译失败因为父类和子类都没有定义成员变量b
}
} 这里需要注意的是 当父类与子类成员名字一致时优先访问自己的成员变量。当访问成员变量时优先访问自己的若没有再去访问父类的若子类与父类都没有会发生编译错误。 成员变量是这样成员方法也是这样调用成员方法时优先考虑子类自己的若没有则去父类中查找都没有就会报错。
public class Base {
public void ways1(){
System.out.println(Base中的ways1());
}
public void ways2(){
System.out.println(Base中的ways2());
}
}
public class Derived extends Base{
public void ways1(int a) {
System.out.println(Derived中的way1(int)方法);
}
public void ways2(){
System.out.println(Derived中的ways2()方法);
}
public void ways3(){
ways1(); // 调用的是父类中的因为父类中午参数
ways1(20); // 传递参数访问子类中的way1(int)
ways2(); //默认访问子类中的ways2
}
} super关键字 上面我们说了当访问的成员或变量子类与父类同名时默认访问的是子类的那么如果就像访问父类的呢这里就需要使用到super关键字了。他可以在子类方法中访问父类的成员 class Country {String name;void value() {name China;}
}class City extends Country {String name;void value() {name Shanghai;super.value(); //调用父类的方法System.out.println(name); //默认打印子类中的chinaSystem.out.println(super.name); //使用super关键字调用父类中的name}public static void main(String[] args) {City cnew City();c.value();}
}
运行结果 Shanghai China 在子类方法中如果想要明确访问父类中成员时借助super关键字即可。 注意 super关键字只可以在非静态的方法中访问。super关键字是在子类中调用父类成员使用的。 子类的构造方法 我们在实例化子类对象时会调用子类的构造方法然而其实子类的构造方法在调用之前编译器已经偷偷地将父类的构造方法调用过一次了只是没有显示而已我们可以这样理解子类中的成员变量其实是由两部分构成的一部分是自己的另一部分是从父类中继承下来的所以必须先要把从父类中继承的成员变量初始化了然后才初始化自己的成员变量。 正所谓父子父子先有父才能有子。 public class Base {
public Base(){
System.out.println(Base());
}
}
public class Derived extends Base{
public Derived(){
// super();
System.out.println(Derived());
}
}
public class Test {
public static void main(String[] args) {
Derived d new Derived();
}
}
运行结果Base() Derived() 总结 当父类中显式定义无参或者默认的构造方法那么在子类中都默认调用了父类无参数的构造方法。当自行定义有参数的父类构造方法时子类的构造方法中不在默认提供调用父类构造方法的操作。需要用户在子类的构造方法中自行调用否则编译错误。当在子类中调用super()必须将super()放到第一行,否则编译错误。在子类的构造方法中不能同时出现super()和this因为从语法上他们都要放到第一行。 super和this的区别
这里提醒一下不懂this的uu们看我的上一篇文章。 this 相当于是指向当前对象本身可以理解为指向当前对象的指针(当然java中没有指针只是这样方便理解)。 这里介绍this的几种用法:
.普通的直接引用:直接使用this.×××来引用当类中的成员变量与成员函数中的参数同名时this.成员变量用来指代当前对象的引用 class Person {private int age 10;public Person(){System.out.println(初始化年龄age);
}public int GetAge(int age){this.age age; //调用的是当前对象Harry的age形参的agereturn this.age;}
}public class test1 {public static void main(String[] args) {Person Harry new Person();System.out.println(Harrys age is Harry.GetAge(12));}
} 用来调用另一种构造方法 public class Chinese { Chinese() { System.out.println(无参数构造方法 A chinese coder.); } Chinese(String name) { System.out.println(含一个参数的构造方法 his name is name); } Chinese(String name, int age) { this(name);// 调用具有相同形参的构造方法3 System.out.println(两个形参的构造方法his age is age); } public static void main(String[] args) { Chinese cn new Chinese(); cn new Chinese(codersai); cn new Chinese(codersai, 18); }
} super可以理解为一个指向父类对象的指针完成对父类对象的引用。 普通的直接引用super.×××引用父类对象的成员变量 子类中的成员变量或方法与父类中的成员变量或方法同名使用super.×××来调用父类的成员。 引用构造函数子类中的构造方法执行之前要先调用父类中的super(),且必须是第一行。
初始化代码运行顺序 静态代码块执行 实例代码块执行 构造方法执行 这三种代码块的运行顺序是怎么样的呢
class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name name;
this.age age;
System.out.println(Person构造方法执行);
}
{
System.out.println(Person实例代码块执行);
}
static {
System.out.println(Person静态代码块执行);
}
}
class Student extends Person{
public Student(String name,int age) {
super(name,age);
System.out.println(Student构造方法执行);
}
{
System.out.println(Student实例代码块执行);
}
static {
System.out.println(Student静态代码块执行);
}
}
public class TestDemo4 {
public static void main(String[] args) {
Student student1 new Student(张三,19);
System.out.println();
Student student2 new Student(ningzhiyuan,20);
运行结果: Person 静态代码块执行 Student 静态代码块执行 Person 实例代码块执行 Person 构造方法执行 Student 实例代码块执行 Student 构造方法执行 Person 实例代码块执行 Person 构造方法执行 Student 实例代码块执行 Student 构造方法执行 由此我们知道了代码块的执行顺序父类静态代码块子类静态方法父类实例代码块 父类构造方法子类实例代码块子类构造方法。并且静态代码块只执行一次。
访问限定符 java中为了更好的封装建立了访问限定符让数据封装起来数据更加安全。 这些限定符决定了数据在哪里可以使用哪里不可以使用对于数据权限的管理非常有效。也提醒我们后面使用数据之前应该了解数据的权限避免写出错误的代码。