java的一些笔记。只针对自己看懂。


overload 重载 三个条件

1.在同一个类当中
2.功能类似方法名相同
3.参数列表不同
①个数不同
②类型不同
③顺序不同

方法重载和返回值类型无关
//这两个方法有没有发生重载呢?
//这不是重载 这是方法重复了。

public static int m5(){
 return 1;
 }
 public static doule m5(){
 return 1.0;
 }
 执行编译会报错‘已在方法中定义了方法m5()
 public static doule m5()
 
 方法重载和修饰符列表无关
 void m6(){
 
 }
 
 public static void m6(){
 
 }

方法自己调用自己,就是方法递归。

使用递归,计算1到n的和。
public static int sum(){
if(n == 1){
return 1;
}
return n + sum(n-1);
}

解析

3 + 2 +1

1/ sum(3) = 3 + sum(2)
2/ sum(3) = 3 + 2 + sum(1)
3/ sum(3) = 3 + 2 + 1

return n + sum(n-1) // 3 + sum(3-1)
3 + 2 + sum(1)
3 + 2 + 1

阶乘
result = resulti // 2
1
2
result = resulti //6
2
3
result = resulti //24
6
4
result = resulti //120
24
5

面向对象的编程语言的三大特征

1.封装

在这里插入图片描述

2.继承 extends

继承的作用

基本作用 子类继承父类,代码可以得到复用。
主要作用 因为有了继承关系,才有了后期的方法覆盖和多态机制。

继承的相关特性

B类继承A类,则称A类为超类superclass,父类,基类。
B类则称为子类subclass, 派生类,扩展类
class A {}
class B extends A {}
不支持多继承
但有时候会产生简介继承的效果,例如
class C extends B
class B extends A
也就是说C直接继承B其实C还简介继承A
构造方法不能继承,剩下的都可以继承。
但是私有的属性无法在子类中直接访问。
Java中的类没有显示的继承任何类,则默认继承Object类。也就是说一个对象与生俱来就有Object类型中的所有的特征。
继承也是存在缺点的。耦合度高,父类修改,子类牵连。

通过子类对象调用继承过来的方法

本质上,子类继承父类之后,是将父类继承过来的方法归为己有。
实际上调用的也不是父类的方法,是他子类自己的方法。

满足什么条件,可以使用继承?

首先要产生重复的代码。
凡是 is a 能描述的,都可以继承。
Cat is a Animal
Dog is a Animal
Credit Account is a Account
A is a B 说得通的

Object类的toString()

作用是 将Java对象 转换成字符串的形式。

继承关系的注意事项

1.父类私有的成员(成员变量或成员方法)不能被继承.(如果要获取成员变量的值,可以通过非私有成员方法获取)
2.父类的构造函数是不能够被继承
3.创建子类的对象时默认会先调用父类无参构造器.
4.千万不要为了减少重复代码而去继承,只有真正存在继承关系时,才去继承

3.多态

基础语法

1. 学习点多态语法之前,我们需要普及两个概念。
第一个 向上转型
子 - - -> 父
第二个 向下转型
父 - - -> 子
Java中允许向上转型,也允许向下转型。
无论是向上转型还是向下转型,两种类型之间必须有继承关系,没有继承关系编译器报错。
2. 多态指的是
父类型引用指向子类型对象。
包括变季阶段和运行阶段
编译阶段 绑定父类的方法
运行阶段 动态绑定子类型对象的方法。

向上转型
public class Animal {
	public void move() {
		System.out.println("动物在移动");
	}
}
public class Bird extends Animal{
	public void move() {
		System.out.println("Bird在fly");
	}
}
public class Cat extends Animal{
	public void move() {
		System.out.println("Cat在走猫步");
	}
}
public class Test01 {
	public static void main(String[] args) {
		Animal a1 = new Animal();
		a1.move();

		Cat c1 = new Cat();
		c1.move();

		Bird b1 = new Bird();
		b1.move();
		a2.move();
		//编译器只知道a2的类型是Animal
		//运行的时候堆中创建的对象是Cat对象。
		Animal a2 = new Cat();
		a2.move();  //输出的是猫。
		Animal a3 = new Bird();
		a3 .move();		
}
	向上转型
	Animal a2 = new Cat();
	Animal a3 = new Bird();

多态表示多种形态,
编译的时候是一种形态 静态绑定
运行的时候是一种形态。动态绑定。
多态实际上指的就是父类型的一个引用指向了子类型对象。

向下转型

当你需要访问的子类对象中特有的方法,此时必须进行向下转型。

Animal a5= new Cat();
Cat x = (Cat)a5;
x.catchMouse();

a5是啥呀,a5是一个变量。
是一个引用。

向下转型有风险吗。

Anmimal a6= new Bird(); 
/*编译器检测到a6这个引用是Animal类型,
而Animal和Cat直接存在继承关系所以可以向下转型。编译没毛病。

运行阶段,堆内存实际创建的的对象是Bird对象,
在实际运行过程中,拿着Bird对象转换成Cat对象就不行了。
因为Bird和Cat没有继承关系。*/
Cat y =(Cat)a6;
y.catchMouse();

运行时出现异常,这个异常和空指针异常一样非常重要,也非常经典。
java.lang.ClassCastExceptiong:类型转换异常
java.lang.NullPointerException:空指针异常

instanceof

怎么避免异常发生。
新的运算符: instanceof

  1. instanceof可以在运行阶段动态判断引用指向的对象的类型
  2. instanceof的语法
    (引用 instanceof 类型)
  3. 运算结果只能是true或false
  4. 假设 c 是一个引用 c变量保存了内存地址 指向了堆中的对象
    假设 (c instanceof Cat) 为true表示
    c引用指向的堆内存中的Java对象是一个Cat
    假设 (c instanceof Cat) 为false表示
    c引用指向的堆内存中的Java对象不是一个Cat
    任何时候 任何地点 对类型进行向下转型时,一定要使用instanceof
    intanceof例子。
多态在开发中的作用

类和对象的概念

  • 什么是类,类是一个抽象的概念,是一个模板。这个模板当中,描述了共同特征。

  • 什么是对象,对象是实际存在的个体。
    在Java语言中,要想的到对象,必须先定义类,对象是通过类这个模板创造出来的。
    类就是一个模板‘类中描述的是所有对象的共同特征信息。
    对象就是通过类创建出的个体。
    对象还有另外一个名字,叫做实例。

  • 通过类创建对象的过程我们可以称为’创建,也可以称为 实例化。
    通过对象提取类,多个对象具有共同特征,进行思考总结抽取共同特征的过程,叫做抽象。

类 = 属性+方法
属性源于 动态。 方法源于 静态。

类的定义

  • 怎么定义一个类,语法格式是什么?
[修饰符列表] class 类名{
	类体 = 属性+方法
	属性在代码上以变量的形式存在 描述状态
	方法描述动作 行为。
}
  • 为什么属性是以变量的形式存在的?
    因为,属性对应的是数据。

局部变量,成员变量,实例变量

  1. 变量 在方法体声明的变量叫做局部变量 在方法体之外 类体内声明的变量叫 成员变量

  2. 局部变量只在方法中有效,方法体执行结束之后该变量的内存就释放了。

  3. 实例变量 实例变量都是基于特定实例的,实例变量不会在实例之间共享,也就是说,每一个对象的实例都有自己的一个实例变量。

创建对象的语法是什么。

类型 变量名 = new 类名();

数据类型包括两种
基本数据类型 byet short int long float double boolean char
引用数据类型 String XueSheng…
java中所有的类都属于引用数据类型

方法调用时,参数的传递。

Java中变量赋值的原理是什么?
永远都是一个规则,将盒子中保存的那个值,复制一份传过去。
不过这个值,可能是一个数字,也可能是一个对象的内存地址。

package chapter9_canshuchuandi;

public class Test1 {
	public static void main(String[] args) {
		int i = 10;
		add(i);//把盒子中的 值 复制一份传给add
		System.out.println("main --->" + i);

	}
	public static void add(int i) {
		i++;
		System.out.println("add --->" + i);
	}
}
//11
//10
package chapter9_canshuchuandi;

public class Test2 {
	public static void main(String[] args) {
		Person p = new Person();
		//更改了堆中Person对象中实例变量的值
		p.age = 10;
		//复制了一个地址传递给参数。地址指向Person对象
		add(p);
		System.out.println("main--->" + p.age);

	}
	//方法的参数可以是基本数据类型 也可以是引用数据类型
	public static void add(Person p) {
		p.age++;
		System.out.println("main--->" + p.age);

	}
}

class Person{
	int age;
}
//11
//11

Constructor 构造方法

  • 可以去看动力节点p239

1. 什么是构造方法,有什么用?

	构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,以及i实例变量的初始化。换句话说,==构造方法是用来创建对象==,并且同时给对象的属性赋值。注意实例变量没有手动赋值的时候,系统会赋值默认值。
  1. 重点,当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法。而这个构造方法被称为缺省构造器。

3. 怎么调用构造方法?

new 调用构造方法

 调用构造方法语法格式
 new 构造方法 (实际参数列表);
 调用普通方法 语法格式
 类名.方法名()
 如果在同一类中 类名.可以省略

4. 构造方法的语法结构是什么?

[修饰符列表]  构造方法名(形式参数列表){
	构造方法体;
	通常在构造方法体当中给属性值,完成属性的初始化。
}

注意
第一 修饰符列表目前统一写 public。千万不要写piblic static
第二 构造方法名和类名必须一致。
第三 构造方法不需要指定返回值类型,也不能写void,写上void表示普通法。就不是构造方法了。

普通方法的语法结构

[修饰符列表]  返回值类型  方法名 (形式参数列表){
	方法体;
	}

在这里插入图片描述

5. 实例变量是在什么时间进行赋值的?

思考,实例变量没有手动赋值的时候,实际上系统会默认赋值,那么这个默认赋值操作是在什么时候进行的?
是在类加载的时候给这些实例变量赋值吗?
不是,实例变量是在构造方法执行的过程中完成初始化的,完成赋值的。

一个困扰自己的问题。用一段代码解释。

public class User{
	//这是一堆成员变量的实例变量。
	int id;
	String name;
	int age;
	//另一个class的new调用我就不写了。主要看下面。

public User(){
//这里一般都是空着  实际上有三行代码你看不见
	id = 0;
	name =null;
	age =0;
}
public User(int i,String s,int a){
//所以这里一定要这个搞一下。不然就没反应。
	id = i;
	name =s;
	age =a;
}
public User(int id ,String name ,int age ){
//这样搞和上面一样,只是参数看起来更高级
	this.id = id ;
	this.name = name ;
	this.age = age ;
}
}

实例方法

创建方法总结。

//实例方法 语法格式
 public 返回值  方法名(){
 }
//构造方法 语法格式
方法名和类名一致才行不然报错。
public 方法名(){
 }
//静态方法语法格式
public static 返回值  方法名(){
 }

调用方法总结。

//静态方法调用
类名.方法名();
//构造方法调用
new 构造方法(实际参数列表)
Student x = new Student();
Student y = new Student(123);
//实例方法调用
引用数据类型类名  引用变量= new 类名();
再通过引用.实例方法名()
MethodTest mt = new MethoTest();
mt.doOther();

static

  1. 翻译为 静态
  2. 所有static关键字修饰的都是类相关的,类级别的。
  3. 所有static修饰的,都是采用类名. 的方式访问的。
  4. static修饰的变量,静态变量
  5. static修饰的方法吗,静态方法

变量根据声明的位置进行划分

  1. 在方法体中声明的变量,局部变量
  2. 在方法体外声明的变量,成员变量。

成员变量又可以分

  1. 实例变量
  2. 静态变量

以下实例的都是对象相关的,访问时采用 引用. 的方式访问
实例相关,的必须先有对象,才能访问,可能会出现空指针异常。
需要先new对象。

class VarTest{

//成员变量实例变量
int i;
//实例方法
public void m2(){
//局部变量
int x = 200;
}
}

以下静态的,都是相关的,访问时采用 类名. 的方式访问。
不需要对象的参与即可访问,没有空指针异常的发生。

class VarTest{
//成员变量静态变量
static int k;
//静态方法
public static void m1(){
//局部变量
int x = 200;
}
}

什么时候使用静态变量

public class StaticTest02 {
	public static void main(String[] args) {
		Chinese c1 = new Chinese("123455678","zhangsan","China");
		System.out.println(c1.idCard);
		System.out.println(c1.name);
		System.out.println(c1.country);
		Chinese c2 = new Chinese("1234565678","lisi","China");
		System.out.println(c2.idCard);
		System.out.println(c2.name);
		System.out.println(c2.country);
	}
}
class Chinese{
	String idCard;
	String name;
	String country;
	public Chinese(){

	}
	public Chinese(String s1,String s2,String s3) {

	}
}

在这里插入图片描述
java一共有三个变量。
成员变量分为 静态变量实例变量
栈→局部变量
堆→实例变量
方法区→静态变量

public class StaticTest02 {
	public static void main(String[] args) {
		Chinese c1 = new Chinese("123455678","zhangsan");
		System.out.println(c1.idCard);
		System.out.println(c1.name);
		String c= Chinese.country;
		System.out.println(c);

		Chinese c2 = new Chinese("1234565678","lisi");
		System.out.println(c2.idCard);
		System.out.println(c2.name);

	}
}
class Chinese{
	String idCard;
	String name;
	//静态变量 在类加载时初始化 不需要new对象  静态变量的空间就开出来了。
	//静态变量存储在方法区。
	static String country = "China";
	public Chinese(){

	}
	public Chinese(String s1,String s2) {

	}
}

在这里插入图片描述

什么时候使用

类体 = 属性+方法
属性描述 状态
方法描述 动作 行为。

静态方法

开发中,如果是工具类的话,工具类当中的方法一般都是静态的。

实例方法

当这个方法体中,直接访问了实例变量,这个方法一定是实例方法。

静态代码块

  1. 语法是什么?
static {
	java语句;
}
  1. 类加载时执行,并且只执行一次。
  2. 在类加载时执行 并且在main方法执行之前执行
  3. 静态代码块按照自上而下的顺序执行
  4. 静态代码块不是那么常用。
    实际上是sun公司给我们Java程序员的特殊的时刻。这个时机叫做,类加载时机。

代码执行顺序

  1. 对于方法来说,方法体中的代码是有顺序的,遵循自上而下的顺序执行。
  2. 静态代码块1和静态代码块2是有先后顺序的。
  3. 静态代码块和静态变量是有先后顺序。

this

this是什么

  1. this是一个关键字,全部小写
  2. this是什么,在内存方面是怎样的?
    一个对象一个this。
    this是一个变量,是一个引用。this保存当前对象的内存地址,指向自身。
    所以严格意义上来说,this代表的就是当前对象。
    this存储在堆内存当中对象的内部。
  3. this只能使用在实例方法中。 谁调用这个实例方法。this就是谁。
    所以this代表的是当前对象。
    在这里插入图片描述
public class ThisTest {
	public static void main(String[] args) {
		Customer c1= new Customer("zhangsan");
		c1.shopping();
		Customer c2= new Customer("lisi");
		c2.shopping();
	}
}
class Customer{
	String name;
	public Customer() {

	}
	public Customer(String s) {
		name = s;
	}
	public static void aa() {

	}
	public void shopping() {
		//因为上面的c1和c2是局部变量。没法用。所以想要指向对象就用this
		System.out.println(this.name + "正在shopping");
	}
}

一个 报错的例子。

class Student{
	//实例变量 实例变量必须new
	String name;
	public static void m1(){
	//报错。
		System.out.println(this.name);
	//除非你这样 才不会报错
	Student s = new Student();
	System.out.println(s.name);	
	}
}

this.什么时候不能省略

在实例方法中,或者构造方法中,为了区分局部变量和实例变量的时候this.不能省略
除了可以用在实例方法中还可以用在构造方法中

package chapter11_jingtaibianliang;
/*
 1,this可以使用在实例方法中,不能使用在静态方法中。
 2、this大部分情况可以省略,什么时候不能省略呢
 	区分局部变量和实例变量的时候
*/
public class ThisTest03_p271 {
	public static void main(String[] args) {
		Student1 s1= new Student1();
		s1.setNo(10);
		s1.setName("zhangsan");
		System.out.println(s1.getNo());
		System.out.println(s1.getName());

		Student1 s2= new Student1(11,"lisi");
		System.out.println(s2.getNo());
		System.out.println(s2.getName());
	}
}
class Student1{
	private int no;
	private String name;

	public Student1() {
	}
	public Student1(int no,String name) {
		this.no = no;
		this.name = name;
	}
	public void setNo(int no) {
		//区分局部变量和实例变量的时候  不能省略
		this.no = no;
	}
	public int getNo() {
		return no;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		//get获取的是当前对象的名字
		return name; //严格来说这里的this是可以省略的。
	}
}

this()

  1. this除了可以用在实例方法中还可以用在构造方法中
  2. 新语法,通过当前的构造方法去调用另一个本类的构造方法,可以使用一下语法格式
    this(实际参数列表);
    注意构造方法1和构造方法2都必须在同一类中。
  3. this () 语法作用是什么?
    代码复用。
  4. this () 的调用只能出现在构造方法的第一行。
public Date(){
	//this.year = 1970;
	//this.month =1;
	//this.day =1;
	this(1970,1,1);
}
public Date(int year, int month, int day){
	this.year = year;
	this.month =month;
	this.day =day;
}

一段代码总结。

package chapter11_jingtaibianliang;

public class Review02 {
	int i;

	public void m1() {
	};
	public void m2() {
	};
	public void x() {
	//这个方法是实例方法,执行这个方法的过程中,当前对象是存在的。
		this.m1();
		m2();
		m3();
		m4();
		System.out.println(i);
	};
	public static void m3() {
	};
	public static void m4() {
	};
	public static void main(String[] args) {
	//main方法是静态的。没有this。m1(); m2()必须通过引用.的方式访问。
		m1();  //报错
		m2();  //报错
		m3();
		m4();
		Review02 r = new Review02();
		r.m1();
		r.x();
	}

}

package chapter11_jingtaibianliang;

public class Review {
	public static void main(String[] args) {
		int i = 100;
		Student02 s = new Student02();
		s.study();
	}
//	public void eat() {
//		Student02 s = new Student02();
//		s.study();
//	}
}
class Student02{
	private int no;
	private String name;

	public Student02(){
		this(1001,"zhangsan");
	}
	public Student02(int no,String name){
		this.no = no;
		this.name = name;

	}
	public void setName(String name) {
		this.name =name;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public int getNo() {
		return no;
	}

	public void study() {
		System.out.println(name + "is studying");
		System.out.println(this.name + "is studying");
		System.out.println(getName() + "is studying");
		this.eat();
		eat();
	}
	public void eat() {
		System.out.println(name + "is eating at resturant");
		m1();
		Student02.m1();
	}
	public static void m1() {
		System.out.println("Student's m1 method executd!");

	}
}

输出
zhangsanis studying
zhangsanis studying
zhangsanis studying
zhangsanis eating at resturant
Student’s m1 method executd!
Student’s m1 method executd!
zhangsanis eating at resturant
Student’s m1 method executd!
Student’s m1 method executd!

方法覆盖 重写 Override

子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,子类有权堆这个方法进行重新编写,有必要进行方法的重写。

条件

  1. 两个类必须是继承关系
  2. 重写之后的方法和之前的方法具有
    相同的返回值类型
    相同的方法定义
    相同的形式参数列表
  3. 访问权限不能更低,可以更高。
    public
    protected没有public开放
  4. 重写之后的方法不能比之前的方法抛出更多的异常,可以更少。

注意事项

  1. 方法覆盖只针对方法,和属性无关。
  2. 私有方法无法覆盖
  3. 构造方法不能被继承,所以构造方法也不能被覆盖。
  4. 方法覆盖只是针对于实例方法,静态方法覆盖没有意义。

关于方法覆盖时的返回值类型

复习一下,
什么条件满足后,会构成方法的覆盖呢?
1,两个类必须是继承关系
2,父类中的方法和子类重写之后的方法
具有相同的方法名,相同的形式参数列表,相同的返回值类型。

学习了多态机制之后,
相同的返回值类型可以修改一下吗?
对于返回值是基本类型来说,必须一致
对于引用数据类型来说,重写的时候返回值可以由大变小,但是基本不会用到。

super概述

super是一个关键字,全部小写。

super和this对比着学习。

this :
this 能出现在实例方法和构造方法中。
this 的语法是 : “this” “this()”
this 不能使用在静态方法中。
this . 大部分情况下是可以省略的。
this . 什在区分实例变量和局部变量时候不可以省略。
this() 只能出现在构造函数的第一行。通过当前的构造方法去调用"本类"中其他的构造方法,目的是代码复用。

super:
super 能出现在实例方法和构造方法中。
super 的语法是 “super” “super()” .
super. 大部分情况下是可以省略的。
super 不能使用在静态方法中。

super() 只能出现在构造函数的第一行。通过当前的构造方法去调用"父类"中其他的构造方法,目的是代码复用。也可以这样理解,在创建子类对象之前,先初始化父类型特征。

super()
表示通过子类的构造方法调用父类的构造方法。

下面这段代码说明了模拟现实世界中的这种场景 要想有儿子,需要现有父亲。↓

public class SuperTest01 {
	public static void main(String[] args) {
		new B();
	}
}
class A{
	public A() {
		System.out.println("A class");
	}
}
class B extends A{
	public B() {
		System.out.println("B class");
	}
}
//最后执行输出的
//	A class
//	B class

重要结论

super()

当一个构造方法第一行
既没有this()又没有super()的话,默认会有一个super()
表示通过当前子类的构造方法 调用 父类的 无参数构造方法
所以必须保证父类的无参数构造方法是存在的。

public class SuperTest01 {
	public static void main(String[] args) {
		new B();
	}
}
class A{
//	public A() {
//		System.out.println("A class");
//	}
	public A(int i) {
		System.out.println("A class的有参构造方法执行");
	}
}
class B extends A{
//	public B() {
//		super();
//		System.out.println("B class");
//	}
	public B() {
	//调用父类中有参数的构造函数
		super(123);
		System.out.println("B class的有参数构造方法执行");
	}
}

this和super在第一行只能存在一个。 默认存在super。

子类构造方法执行时,必然调用父类构造方法。

子类构造方法执行时,必然调用父类构造方法。

super(实参)的用法

super(实参)的用法

super使用时,后面必须有一个 .

结论

  1. this可以单独用
  2. super不可以,后面必须有一个 .
    super不是引用 super也不保存内存地址 super也不指向任何对象
  3. super只是代表当前对象内部的那一块父类型的特征。
  4. super和this不能使用在static语句里。可以使用在实例和构造方法中。

super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【调用父类的构造方法】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值