我们经常说JAVA语言有三个特点,分别是继承,封装和多态,以下就是我个人初步理解整理的一些继承方面的知识,供参考
继承
通过抽象相同的属性和行为,形成一个父类,父类的属性给其他需要此属性的类使用就发生了继承(extends ) ,实现了代码的重用
创建一个父类
public class father {
public String eat;
public String eye;
public String hair;
}
创建一个子类,继承父类的方法和属性
public class son extends father {
// 子类继承与父类,可以共享父类的属性和,也可以添加自己特有的属性和方法
public String glasses;
public static void main(String[] args) {
son s = new son();
// 继承的父类的属性
s.eat = "吃饭";
s.eye = "bleak";
s.hair = "yellow";
// 子类自己特有的属性
s.glasses = "近视";
}
}
继承的优点
* 代码的重用性
* 父类的属性和方法可以给子类共享
* 子类可以继续扩展父类的属性和方法
* 设计应用程序变得更简单
继承的使用原则
* 观察要使用的类,确定它们之间共同的和特有的特征和行为,将这些共性数据迁移到父类。以便于子类中进行方法和属性的重用
* 对于不同的特征和行为,在子类里可以重新定义
单继承与多继承
* C++中允许一个子类有多个父类
* 在JAVA中这是不允许的,在JAVA中一个类只能有一个父类,一个类不能同时继承两个父类
所有的类的根类都是Object,即所有的类都是直接或间接继承于Object
构造方法和继承
如果需在new对象之前初始化数据,给属性赋,可以用构造方法
构造器
构造器也叫构造方法,构造方法的方法名和类名相同, 没有返回类型包括void,利用构造方法,可以参数该类的对象。
构造方法的作用
1. 为对象分配内存空间
2. 初始化成员变量
3. 返回该对象的引用
如果一个类没有定义构造方法,虚拟机会默认分配一个无参构造方法给该类,如果一个类定义了构造方法,这时默认的无惨构造方法就会消失。构造方法在产生对象时调用。通常使用构造方法做一些初始化动作。只在对象创建时调用一次。
构造器是加载在对象之前(new之前),如果new对象时需要用初始化成员变量或返回对象引用,可以用构造器方法。成员方法(非静态方法)是加载在对象后(new之后),需用对象名.方法名调用。需注意,构造法的方法体需等成员变量初始化完成后才会开始执行
有参构造器初始化变量
public class Man {
public String name;
public int age;
public String tel;
public Man(){}
//this关键字意思为:我的String name属性值就是传进来的参数name的值
public Man(String name,int age,String tel){
this.name=name;
this.age=age;
this.tel=tel;
}
}
public class Test {
public static void main(String[] args) {
Man m=new Man("AAA",25,"1568001XXXX");
System.out.println(m.name+" "+m.age+" "+m.tel);
}
}
静态方法和非静态方法
看方法里面是否需要使用对象属性,static方法不能使用this关键字调用类属性。方法要调用到类的属性,需用this表示。否则会出现优先找同名的形参或局部变量,如果没有,才会找类属性
继承的原理
* 子类对象创建之前,会优先产生父类对象,然后在父类对象的基础上,扩展子类特有的属性和方法,所以子类对象中包含完成的父类对象,就可以重用父类中定义的方法和属性
* 子类对象在创建之前,需要通过super()方法调用父类的构造方法,产生父类的对象。如果子类构造方法中没有书写super(),这时,需虚拟机会自动调用super()。如果父类中没有无参构造方法,子类必须通过super(参数)显示调用
代码演示
public class A {
public A(int j){
System.out.println("A的构造方法");
}
// public A(){}
}
class B extends A{
public B(){
/*此位置系统会默认添加一个无参super();方法,为父类方法,如果父类为有参构造方法,需手动
* 调用super方法,并对super传入对应的参数,也可以手工添加一个无参构造方法
*/
super(10);
System.out.println("B的构造方法");
}
super方法也可以用于子类继承的父类成员变量的初始化赋值
public class Emloyee {
public String job;
public int money;
public Emloyee(String job,int money){
this.job=job;
this.money=money;
}
}
class Sell extends Emloyee{
public Sell(){
super("销售员",2000);
}
}
方法的重载
重载是发生同一个类中,两个方法,方法名相同,参数列表不同(参数个数,类型,顺序),会发生方法的重载,执行不同的方法体,和返回类型无关,调用方法时根据方法的参数决定调用哪个方法重载
方法的重写
重写发生在父类和子类之间(继承才会重写),子类的方法名和父类相同,参数列表相同,返回类型相同,方法体不同。当对子类对象进行方法调用时,会优先调用子类重写的方法。
方法重写代码演示
public class Region {
public void getMoney() {
System.out.println("发展经济");
}
}
class GL extends Region{
public void getMoney(){
System.out.println("发展旅游");
}
}
class SD extends Region{
public void getMoney(){
System.out.println("发展农业");
}
}
class SC extends Region{
//为重写getMoney方法
}
toString 重写方法
因默认Object方法toString方法默认打印引用类型的地址,所以如果需要测试打印引用 的值,需重写toString方法
public class Student {
public String name;
public int age;
public String sex;
public Student(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
@Override
public String toString(){
return this.name+" "+this.age+" "+this.sex;
}
}
建一个测试类
public class toStringTest {
public static void main(String[] args) {
Student s=new Student("张三",30,"男");
System.out.println(s);
}
}
输出结果:因为重写了toString方法,所以会打印值,如果没重写,会打印地址
equalse方法重写
因为String 类重写了equalse方法,所以String方法使用equals比较时比较的的是地址对应的内容
引用类型进行比较,equalse是比较的两个引用类型的地址
public class Student {
public String name;
public int age;
public String sex;
public Student(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
//重写equals方法
@Override
public boolean equals(Object obj){
Student s=(Student)obj;
return this.age==s.age&&this.name==s.name;
}
}
final关键字 常量/最终
* final关键字可以修饰类,方法,变量。修饰类表示该类不能被子类所继承,修饰方法表示该方法不能被子类重写,修饰变量表示该变量的内容不能修改
* 用final修饰的常量 基本数据类型值不能改变,引用数据类型引用地址指向不能改变,这个变量不能指向其他变量,但是变量内的值可以改变,地址不能改变
* 需注意,当一个类被final修饰,就不能被继承,只能有父类,不能有子类。方法被声明为final ,子类也不能重写被final修饰的方法
网友评论