Java新手:static、代码块、继承、抽象类

1 static 关键字
  1. static是静态修饰符,一般用来修饰类中的成员变量和成员方法。
  2. 被static修饰的成员变量属于类,不属于这个类的某个对象,多个对象共享同一个static成员变量。
    被static修饰的成员可以通过类名直接访问,格式是:类名.静态成员变量名,类名.静态成员方法名()
    静态的加载优先于对象,随着类的加载而加载。
public class StaticDemo {
  public static void main(String[] args) {
	Person.classRoom="101";
	Person p1=new Person();
	p1.name="张三";
	p1.speak();
	Person p2=new Person();
	p2.name="李四";
	p2.speak();
  }
}
class Person{
	String name;
	static String classRoom;
	public void speak(){
		System.out.println(name+"---"+classRoom);
	}
}

输出结果:

张三---101
李四---101

注意:

  1. 静态成员方法只能直接访问静态成员变量和调用静态成员方法,不可以调用费静态成员变量和非静态成员方法。
  2. 非静态成员可以访问非静态成员也可以访问静态成员。
  3. this是调用这个方法的当前对象,静态的方法中没有this对象。
  4. 静态的优缺点:静态对对象的共享数据提供单独空间的存储,节省空间,没有必要每一个对象都存储一份,可以直接使用类名调用,不用再堆内存创建对象。但是访问出现局限性,只能访问静态。
  5. 如果想要不能创建对象,把构造方法写成私有即可。
  6. 类变量与实例变量辨析:
    类变量:即静态变量,定义在类中方法外,所在内存区域是方法区,生命周期是随着类的加载而加载,特点是无论创建多少对象,类变量仅在方法区中且仅有一份。
    实例变量:即非静态变量,所在位置是定义在类中方法外,生命周期是随着对象的创建而创建,所在内存是堆,特点是每创建一个对象,堆中的对象中就有一个实例变量。
2 代码块
  1. 局部代码块
    以{}划定的代码区域,定义在方法或语句中,可以控制变量的生命周期,只需要关注作用域的不同,方法和类都是以代码块的方式划分界限。
public static void main(String[] args) {
	  {
		 int i=0;
	  }
	 // System.out.println(i);无法访问i,超出i的作用域范围
  }
  1. 构造代码块
    定义在类中成员位置的代码块
 public static void main(String[] args) {
	 Student s1= new Student();
	 Student s2=new Student();
  }
  //学生类
  public class Student {
	private String id;//学号
	private String name;//姓名
	private String age;//年龄
	private String address;//地址
	{
		System.out.println("学生类");
	}
	public Student() {
		System.out.println("无参构造");
	}
	public Student(String id, String name, String age, String address) {
		System.out.println("有参构造");
		this.id = id;
		this.name = name;
		this.age = age;
		this.address = address;
	}

输出结果:

学生类
无参构造
学生类
无参构造

注意: 抽取出来构造方法中的共性,然后写成构造代码块,只要创建对象,都会执行一遍,并且在构造方法之前执行,用于执行所有对象均需要的初始化动作。

  1. 静态代码块
    定义在成员位置,使用static修饰的代码块
 public static void main(String[] args) {
	 Student s1= new Student();
	 Student s2=new Student();
  }
  //学生类
  public class Student {
	private String id;//学号
	private String name;//姓名
	private String age;//年龄
	private String address;//地址
	{
		System.out.println("学生类");
	}
	public Student() {
		System.out.println("无参构造");
	}
	public Student(String id, String name, String age, String address) {
		System.out.println("有参构造");
		this.id = id;
		this.name = name;
		this.age = age;
		this.address = address;
	}

输出结果:

学生类
无参构造
无参构造

注意: 静态代码块优先于主方法main执行,优先于构造代码块执行,优先于对象,当以任何形式第一次使用到该类时执行,随着类的加载而加载,只加载一次,用于给静态变量赋值,加载类时需要做的一些初始化。

3 继承
  1. 继承是指多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,这多个类就可以获取到父类的成员了。
  2. 继承的特点:
    类只支持单一集成,不允许多继承,一个类只能有一个直接父类。
    多个类可以继承一个父类,
    一个类的父类可以再去继承另外的类,支持多层继承。
    一个类是某一个类父类的同时,也可以是另一个类的子类。
public class ExtendsDemo {
	public static void main(String[] args) {
		Student1 s =new Student1();
		s.sleep();
		Child c =new Child();
		c.sleep();
		c.speak();
	}
}
//人
    class Person1{
    	String name;
    	String sex;
		public void sleep(){
    		System.out.println("睡觉");
    	}
    }
    //学生
    class Student1 extends Person1{
		public void speak(){
    		System.out.println("学生说话");
    	}
    }
    //老师
    class Teacher extends Person1{
    	public void speak(){
    		System.out.println("老师说话");
    	}
    }
    //孩子
    class Child extends Student1{
    	
    }

输出结果:

睡觉
睡觉
学生说话
  1. 继承中成员变量的特点:
    子类只能获取父类的非私有成员,
    如果子父类成员变量的名字不一样就获取父类的成员变量
    如果子父类成员变量的名字一样就获取子类的成员变量
    如果有局部变量就使用局部变量,如果没有局部变量,有子类的成员变量就使用子类的成员变量,如果这两个都没有,有父类的成员变量就使用父类的成员变量,如果都没有就出错了。
    成员变量是属于对象的。
  2. this和super的去区别:
    super:是子类对象的父类引用,是可以调用父类的成员变量和成员方法的。在子类的构造方法第一行调用父类的构造方法。
    this:是当前对象的引用,可以调用子类的成员变量和成员方法,在子类的构造方法第一行调用子类其他构造方法。若取得当前对象没有的成员变量也可以调用,调用的是父类的成员变量。
public class ExtendsDemo {
	public static void main(String[] args) {
		Student1 s =new Student1();
		s.speak();
	}
}
//人
    class Person1{
    	String name="人";
    	int age =18;
    }
    //学生
    class Student1 extends Person1{
    	String name="学生";
    	String sex ="女";
		public void speak(){
			String name="张三";
    		System.out.println(super.name);
    		System.out.println(this.name);
    		System.out.println(name);
    		System.out.println(sex);
    		System.out.println(age);
    	}
    }

输出结果:

人
学生
张三
女
18
  1. 继承中成员方法的特点:
    子类中没有这个方法就调用父类的,子类中重写了这个方法就调用子类的。
  2. 方法的重写:
    在子父类中,子类的方法和父类的方法完全一样,子类重写父类的方法,在子类对象调用中就会调用子类的方法。
    应用场景:
    当父类的方法不能完全满足子类使用,子类就要重写父类的方法,并可以在方法中使用关键字super调用父类的方法,这样即保留了父类的功能,也可以拥有子类特有的功能。
    注意事项:
    1 、 子类不可以重写父类私有的方法,根本看不到父类的私有方法。
    2 、子类重写父类的方法,权限必须大于等于父类方法的权限。
    @Override:是方法重写的注解
  3. 方法的重载:在一个类中,有多个重名的方法,但是参数(个数、类型、顺序)不一样,与返回值无关。
public class ExtendsDemo {
	public static void main(String[] args) {
		Student1 s =new Student1();
		s.speak();
		s.sleep();
		s.call();
	}
}
    class Person1{
    	public void speak(){
    		System.out.println("人说话");
    	}
    	public void sleep(){
    		System.out.println("睡觉");
    	}
    	public void call(){
    		System.out.println("打call");
    	}
    }
    //学生
    class Student1 extends Person1{
    	@Override
		public void speak(){
			super.speak();
			System.out.println("学生说英语");
    	}
    	@Override
    	public void sleep(){
    		System.out.println("学生11点睡觉");
    	}
    }

输出结果:

人说话
学生说英语
学生11点睡觉
打call
  1. 继承中构造方法的执行顺序:
    1、在子类中,创建子类对象,调用子类的构造方法。
    2、在子类的构造方法的第一行代码如果没有调用父类的构造或者没有调用其他子类的构造,就默认调用父类的无参构造
    3、肯定会先把父类的构造执行完毕,再去执行子类构造中的其他代码。因为需要给父类的成员变量初始化,子类可能会用到,所以要调用父类的构造方法。
public class ExtendsDemo {
	public static void main(String[] args) {
		Student1 s =new Student1();
	}
}
    class Person1{
    	public Person1(){
    		System.out.println("我是父类无参构造");
    	}
    	public Person1(int num){
    		System.out.println("我是父类有参构造");
    	}
    }
    //学生
    class Student1 extends Person1{
    	public Student1(){
    	//super(1);
    		this(1);
    		System.out.println("我是子类无参构造");
    	}
    	public Student1(int num){
    		System.out.println("我是子类有参构造");
    	}
    }

输出结果:

我是父类无参构造
我是子类有参构造
我是子类无参构造

注意:
1、super(实参列表);:在子类的构造方法中使用,用来调用父类中的构造方法,并且只能在构造方法第一行使用。
2、this(实参列表);:在类的构造方法中使用,用来调用本类中的其他构造方法,并且只能在构造方法的第一行使用。

  1. 继承的优缺点:
    优点:提高了代码的复用性,提高了代码的可维护性。
    缺点:类的耦合性增强了(开发的原则应该是高内聚[自己完成某件事的能力]低耦合[类与类的关系])。
4 抽象类
  1. 抽象类的概述:
    在分析事物时,发现了共性内容,就往上提取,但是出现一特殊情况,方法功能声明一样,但是方法功能实现主体不同,这时只抽取方法声明,不抽取方法主体,就是一个抽象方法。
    1、 抽象方法:不同类的方法相似,但是具体实现内容不一样,只抽取他的声明,没有具体的实现方法体,没有具体实现方法体的方法就是抽象方法。
    2、抽象类:有抽象方法的类必须是抽象类
    3、abstract用于修饰方法和类,就是抽象方法和抽象类。
 abstract class Person1{
    	public abstract void eat();
    	public void run(){
    		
    	}
    }
    //学生
    class Student1 extends Person1{
		@Override
		public void eat() {
			// TODO Auto-generated method stub
			System.out.println("学生去食堂吃饭");
		}
    }
    //老师
    abstract class Teacher extends Person1{
    	
    }

注意: 一个类继承了抽象类需要重写父类中所有的抽象方法,例如Student1 ,否则这个类就必须也是抽象类,例如Teacher 。

  1. 抽象类的特点:
    抽象方法只能在抽象类里,
    抽象方法和抽象类必须被 abstract修饰
    抽象类不能创建对象(不能实例化)
    抽象类可以有非抽象方法
    抽象类和类是继承关系
    一个类继承了抽象类要么需要重写父类中所有的抽象方法,要么他自己也是抽象类
  2. 抽象类成员特点:
    抽象类中的成员变量可以有成员变量,也可以有常量
    抽象类中的成员方法可以有抽象方法,也可以有非抽象方法,抽象类不能创建对象,方法可以直接让子类使用。
    抽象类中可以有构造方法,是由子类的super语句来调用,用于对抽象类的成员变量进行初始化
    final:可以修饰类(类不能被继承,不能有子类)、成员变量(变量不能改,是常量,自定义的常量必须初始化,可以选择直接声明时初始化或者构造初始化)、成员方法(方法不能被重写)
    抽象类的关键字abstract不能和哪些关键字共存?
    1、private,子类无法继承到私有的方法,也不存在覆盖,abstract要子类去实现抽象方法。
    2、final,抽象类自己无法创建对象,需要通过子类创建对象,一旦抽象类使用了final,抽象类就没有子类了,抽象方法需要在子类中重写,而加上final无法重写。
    3、static,一旦加上static,就可以通过类名直接访问抽象方法,而抽象方法没有方法体,没有任何意义,也不允许这样做。

猜你喜欢

转载自blog.csdn.net/w_e_i_1201/article/details/83305341