1、继承性
1.1 什么是继承
继承:extends – 多个类拥有相同的属性和方法
- 1.子类继承父类,只能继承非私有的属性和方法,构造方法不能被继承
- 2.子类只能单继承父类
- 3.子类对象在创建之前会先创建父类对象
- 4.子类的构造方法中默认存在super()
super:指向当前类的父类类对象
- 1.super.属性:调用当前类的父类类对象的属性
- 2.super.方法名():调用当前类的父类类对象的方法
- 3.super():调用当前类的父类类对象的无参构造方法
- 4.super(参数列表):调用当前类的父类类对象的有参构造方法
代码示例:
创建父类Animal.java
public class Animal {
public String name;
public int age;
//私有的属性
private char sex;
//私有的方法
private void test(){
System.out.println("父类私有的方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
创建子类Cat.java继承父类
public class Cat extends Animal {
}
创建子类Dog.java继承父类
public class Dog extends Animal{
}
创建Demo01.java
public class Demo01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.setName("橘猫");
cat.setAge(1);
System.out.println(cat.name+":"+cat.getAge());
//子类无法继承父类私有的属性
//System.out.println(cat.sex);
//子类无法继承父类私有的方法
//cat.test();
Dog dog = new Dog();
dog.setName("中华田园犬");
dog.setAge(2);
System.out.println(dog.getName()+":"+dog.getAge());
}
}
注意:
- 使用super调用父类的构造方法,只能在构造方法中的第一行
- 与this调用当前类的构造方法起冲突,所以只能有一个
2、访问修饰符
- public:公有的(任何地方均可访问)
- protected:受保护的 – 本类,同包,非同包子类
- default:默认的、本类,同包 (不写的话,就默认被default修饰)
- private:私有的 – 本类
代码示例:
创建父类Animal.java
public class Animal {
//受保护的属性
protected int id;
//默认的属性
int num;
}
创建父类Cat.java
public class Cat extends Animal {
public void test(){
//同包下的子类可以调用受保护的属性
System.out.println(super.id);
//同包下的子类可以调用默认的属性
System.out.println(super.num);
}
}
创建Demo01.java
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Animal();
//同包下非子类调用受保护的属性
System.out.println(animal.id);
//同包下非子类调用默认的属性
System.out.println(animal.num);
}
}
3、方法重写
3.1 重写的要求
方法的重写:当父类的方法满足不了子类的需求
- 1.必须在继承条件下
- 2.方法名必须相同
- 3.参数列表必须一致
- 4.返回值必须一致
- 5.访问修饰符不能比父类的更严谨
创建父类Animal.java
public class Animal {
public void sleep(){
System.out.println("趴着睡");
}
public void eat(){
System.out.println("吃东西");
}
}
创建子类Cat.java
public class Cat extends Animal {
/*
@Override // 标记方法为重写的方法
public void eat(){
System.out.println("猫吃猫粮");
}
*/
//重写的方法,参数列数必须跟父类的一致
/* @Override
public void eat(int num){
System.out.println("猫吃猫粮");
}*/
//重写的方法,返回值类型必须跟父类一致
/* @Override
public int eat(){
return 1;
}*/
/*@Override
private void eat(){
}*/
//重写的方法,子类的访问修饰符不能比父类的更严谨
/*@Override
void eat(){
}*/
}
创建子类Dog.java
public class Dog extends Animal {
public void eat(){
System.out.println("狗吃狗粮");
}
}
创建Demo01.java
public class Demo01 {
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
cat.sleep();
cat.eat();
dog.sleep();
dog.eat();
}
}
3.2 重写与重载的区别
重载VS重写
- 1.重载的参数列表必须不一致,重写必须相同
- 2.重载是发生在同一个类中,重写是发生在继承关系中
- 3.重载与返回值和访问修饰符无关,重写的访问修饰符必须比父类的更宽松,返回值必须一致
创建ArrayUtils.java
public class ArrayUtils {
//静态方法 -- 遍历int类型数组
public static void print(int[] nums){
for (int num:nums) {
System.out.println(num);
}
}
}
创建User.java
public class User {
//属性
private String name;
private static int age;
//普通方法
public void test1(){
System.out.println("普通方法");
System.out.println(name);
//普通方法可以调用静态方法
//test2();
}
public static void test2(){
System.out.println("静态方法");
//静态方法只能调用静态属性
//System.out.println(name);
//System.out.println(age);
}
}
创建Demo01.java
public class Demo01 {
public static void main(String[] args) {
/*
通过对象调用可以调用普通方法和静态方法
User user = new User();
user.test1();
user.test2();*/
//本类中的静态方法,在main方法中可以直接调用
//test3();
//本类中的普通方法,在main方法中必须要创建对象,通过对象才可以调用
//Demo01 demo01 = new Demo01();
//demo01.test4();
//其他类的静态方法也可以直接调用,不需要经过对象来调用,但是需要指定类名
User.test2();
System.out.println(Arrays.toString(new int[]{1,2,3}));
}
public static void test3(){
System.out.println("本类的静态方法");
}
public void test4(){
System.out.println("本类的普通方法");
}
}
4、super关键字
4.1 super关键字
在子类中,可直接访问从父类继承到的属性和方法,但如果父子类的属性或方法存在重名(属性遮蔽、方法重写)时,需要加以区分,才可专项访问。
4.2 super访问方法
super关键字可在子类中访问父类的方法。
- 使用”super.”的形式访问父类的方法,进而完成在子类中的复用;
- 再叠加额外的功能代码,组成新的功能。
创建父类Animal.java
public class Animal {
int num = 10;
public Animal(){
System.out.println("父类无参构造方法");
}
public Animal(int num){
System.out.println("父类有参构造方法");
}
}
创建子类Cat.java
public class Cat extends Animal {
public Cat(){
//默认存在 --调用父类的无参构造方法,创建父类对象
//super();
//调用父类的属性
System.out.println(super.num);
System.out.println("子类无参构造方法");
}
public Cat(int num){
//默认存在
//super();
System.out.println("子类有参构造方法");
}
}
代码示例:
5、static
5.1 static在方法、属性、构造方法、构造代码块的区别
static:静态 static修饰的东西会随着字节码文件优先于类加载进内存
- 1.修饰方法:
静态方法,不需要进行创建对象就可以直接调用,通过类名直接调用。
属于类不属于对象,静态方法只能调用静态方法或者静态属性。
一般出现在工具类中解决问题。- 2.修饰属性:
静态属性,不需要进行创建对象就可以直接调用,通过类名直接调用。
属于类不属于对象,所有对象共享一份数据。
一般与常量使用,形成静态常量。- 3.构造方法:
无法修饰。- 4.构造代码块:
静态代码块,在类被使用的第一次执行,有且只有一次。
静态代码块>构造代码块>无参构造方法。
静态代码块>静态方法法。
创建ArrayUtils.java
public class ArrayUtils {
//静态方法 -- 遍历int类型数组
public static void print(int[] nums){
for (int num:nums) {
System.out.println(num);
}
}
}
创建User.java
public class User {
//属性
private String name;
private static int age;
//普通方法
public void test1(){
System.out.println("普通方法");
System.out.println(name);
//普通方法可以调用静态方法
//test2();
}
public static void test2(){
System.out.println("静态方法");
//静态方法只能调用静态属性
//System.out.println(name);
//System.out.println(age);
}
}
创建Demo01.java
public class Demo01 {
public static void main(String[] args) {
/*
通过对象调用可以调用普通方法和静态方法
User user = new User();
user.test1();
user.test2();*/
//本类中的静态方法,在main方法中可以直接调用
//test3();
//本类中的普通方法,在main方法中必须要创建对象,通过对象才可以调用
//Demo01 demo01 = new Demo01();
//demo01.test4();
//其他类的静态方法也可以直接调用,不需要经过对象来调用,但是需要指定类名
User.test2();
System.out.println(Arrays.toString(new int[]{1,2,3}));
}
public static void test3(){
System.out.println("本类的静态方法");
}
public void test4(){
System.out.println("本类的普通方法");
}
}