JavaSE学习总结--基本语法,面向对象

第二章

字符串String不是基本的数据类型,String其实是个类,因此它属于引用数据类型。
基本数据类型:变量名指向具体的数值
引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值
字符型char,char占2字节,16位,可存放汉字,只能放单个字符。
char a=‘a’; //任意单个字符,加单引号
char a=‘中’;//任意单个中文字,加单引号
char可以进行运算。char+char,char+int——类型均提升为int,附值char变量后,输出字符编码表中对应的字符。
双精度单精度,双精度的范围更广

声明数组时,int [] a和int a[] 一样,int[] a=new int[]{}
int [ ] [ ] a=new int[ 2][3 ]就是{(1,2,3),(4,5,6)}这样的
如果想输出数组,要使用下面语句
System.out.println(Arrays.toString(arrName));

数组排序 冒泡排序

第三章

public int getAge() {//如果是一个有返回值的方法,那么方法体最后一行是返回相应的数据
		return age;
	}

这种返回值的方法,返回的值就是Int可以定义个int i去接受它的值,返回的就是age,如果没有赋值,在main方法中输出 i 的话是默认值 0

成员变量(属性)和局部变量
成员变量是类内方法体外声明的,存在堆内存。局部变量方法体内声明的,存在栈内存中
成员变量:实例变量和类变量(static修饰的)

方法可变个数的参数,每次传递的参数可能不一样,

public void showInfo(String [] str) {
		
	}
public void showInfo(String ... str) {
		
	}

数组方式传递时如果没有参数需要定义一个空数组,或者p.printInfo(null)
…方式则不需要

构造方法
创建对象时,Person p =new Person();其实这里是在调用构造方法,只不过是类默认的可以在类中不写,调用普通方法是
类点方法名(实参列表)(方法修饰符中有static)
引用点方法名(实参列表)(方法修饰符中 没有static)

当一个方法执行的过程是需要对象参与的,那这个方法一定要定义为实例方法也就是不能用static修饰,例如购物这个方法,每个顾客购物的东西方式是不同的,还有封装中的set和get方法都不能用satic修饰

构造方法是有返回类型的 但是不用写new Person()调用Person类中的无参构造方法,然后赋值给p p有一个数据类型这个数据类型就是Person

一旦显式定义了构造器,则系统不再提供默认构造器

构造器实例化对象的同时,初始化实例变量的内存空间(给实例变量赋值)

关键字this
this是一个引用变量,this变量中保存了内存地址指向自身,this存储在堆内存中
this不能用在static修饰的方法中,因为static方法是通过类名点方法名调用的,没有对象,所以不能使用this

this()用在构造器中,必须写在第一行

public class Person {
	int year;
	int month;
	int day;
	
	/**
	 * 需求:在创建对象时默认的日期是2018 8 8,则无参构造上必须添加上
	 * 如果不止这三行,还要默认很多行的代码,所以在无参构造里考虑调用有参构造方法
	 * 如果使用New的话会创建一个新对象
	 * 可以采用this(2018,8,8)的方式
	 */
	public Person() {
//		this.year=2018;
//		this.month=8;
//		this.day=8;
		this(2018,8,8);//要写在构造器第一行
		
	}


	public Person(int year, int month, int day) {
		
		this.year = year;
		this.month = month;
		this.day = day;
	}


	public int getYear() {
		return year;
	}


	public void setYear(int year) {
		this.year = year;
	}


	public int getMonth() {
		return month;
	}


	public void setMonth(int month) {
		this.month = month;
	}


	public int getDay() {
		return day;
	}


	public void setDay(int day) {
		this.day = day;
	}
	
	public void print() {
		System.out.println(year+"年"+month+"月"+day+"日");
	}
}

关键字super
子类创建对象时,默认调用父类的无参构造
在父类只有有参构造是,子类必须构建一个有参构造,super()必须第一行

public class manKind {
	int sex;
	int salary;
	
//	public manKind() {
//		
//	}
	
	public manKind(int sex,int salary) {
		this.sex=sex;
		this.salary=salary;
	}
	public void manOrWomen() {
		if(this.sex==1) {
			System.out.println("man");
		}else {System.out.println("women");}
		
	}
	
	public void employeed() {
		if(salary==0) {
			System.out.println("no job");
		}else {
			System.out.println("job");
		}
	}
}


public class kinds extends manKind {
public kinds(int sex, int salary) {
		super(sex, salary);//这里的super跟this()差不多,都是在构造器中调用其他的构造器
		
	}
//	public Kinds() {
//		super();
//	}
	String name ;
	@Override
	public void employeed() {
		// TODO Auto-generated method stub
		super.employeed();
	}
	
	}

多态
前提:需要存在继承或者实现关系,需要有覆盖操作(子类可以重写父类方法)
Animal a1=new cat();
编译阶段Animal a1,编译器在检查语法的时候只知道a1是animal类型,在animal字节码文件中找move方法,找到了,绑定上move方法,编译通过,静态绑定成功。
运行阶段,堆内存上创建java对象是cat对象,所以Move的是cat的move方法
编译时一种形态,运行是一种形态,所以叫多态。
多态指的是父类引用指向子类型对象,编译阶段绑定父类的方法,运行阶段动态绑定子类型对象的方法

子类继承父类时,方法会覆盖,属性不会

父类变量可以接受子类对象
Object obj =new Person();

向上转型:子—父
向下转型:父–子
当父类要使用子类特有方法的时候
Animal是父类,cat为子类
Animal a1=new cat();
a1.catchmouse是不能编译的
cat c = (cat)a1;
c.catchmouse能运行

public class Animal {
	public void type() {
		System.out.println("这是一个动物类");
	}
}
public class cat extends Animal {
	public void type() {
		System.out.println("猫走猫步");
	}
	public void catchmouse() {
		System.out.println("猫正在抓老鼠");
	}
	
}
public class Test {
	public static void main(String[] args) {
		
		Animal a=new cat();
		
		a.type();
		//我想运行cat中特有的catchmouse方法,要使用向下转型
		//向下转型有风险,可能转成别的类型的比如bird,
		//就是看Animal a=new cat();左边new的时候是否new错了
		//要判断
		if(a instanceof cat){
			cat c= (cat) a;
			c.catchmouse();
		}		
	}
}

public class Bird extends Animal{
	public void sing() {
		System.out.println("鸟在唱歌");
	}
}
public class AnimalTest {
	public void feed (Animal a) {
		//对于这个程序编写者来说,不知道调用者传过来的是
		//new cat()对象还是new birds()对象
		
		if(a instanceof cat){
			cat c= (cat) a;
			c.catchmouse();
		}		else if(a instanceof Bird) {
			Bird b=(Bird) a;
			b.sing();
		}
	}
}

Person p =new Student();
p.showinfo 调用的是student类的方法

x instanceof A 对象x是不是属于类A或者A 的子类

子类继承父类为什么重写方法,而不是写个新的方法?
如果重写方法名字是相同的,上边那个例子type方法,如果不重写调用的永远是父类的type方法,调不着子类的方法

练习:编写程序实现乐手弹奏不同的乐器发出不同的声音,钢琴,琵琶,二胡。

public class YuQi {
	public void shengyin() {
	}
}
public class YueShou {
	public void tanzou(YuQi y) {
		//编译阶段shengyin()方法是YuQi类的
		//运行阶段hengyin()方法,不一定是谁的,可能是琵琶类的,小提琴类的,
		y.shengyin();
	}
}
public class Erhu  extends YuQi{
	@Override
	public void shengyin() {
		
		System.out.println("二胡的声音是ll");
	}
}
public class Gangqin extends YuQi {
	@Override
	public void shengyin() {
		System.out.println("钢琴的声音是ll");
	}
}
public class pipa extends YuQi {
@Override
public void shengyin() {
	System.out.println("琵琶的声音是ll");
}
}

public class Test {
	public static void main(String[] args) {
		YueShou zhangsan =new YueShou();
		
		Erhu e =new Erhu();
		
		YuQi x=new Erhu();
		YuQi y=new pipa();
		YuQi z=new Gangqin();
		
		zhangsan.tanzou(new Erhu());
		zhangsan.tanzou(e);
		zhangsan.tanzou(y);
	}
}

super
super.和super()也是构造方法,在创建对象之前先初始化父类属性,
当一个构造方法既没有this()又没有super()的话,默认会有一个super();表示通过当前子类的构造方法构造父类的无参构造方法,所以必须爆保证父类的无参构造方法是存在的

public class Person {
	private String name;
	private int sex;
	private int age;
	
	
	public Person() {
		
	}


	public Person(String name, int sex, int age) {
		
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
public class Teacher extends Person  {

	String crouse;
	
	public Teacher(String name, int sex, int age,String crouse) {
		//因为父类的属性是private的所以不能直接赋值
		super( name,  sex,  age);//调用父类有参构造,不写数据类型
		this.crouse = crouse;
	}
	

	public Teacher() {
		
	}

super内存图
在这里插入图片描述

public class Super {
	public static void main(String[] args) {
		Vip v =new Vip("张三");
		v.shopping();
	}	
}

class Customer{
	String name;	
	public Customer() {
			
	}
	public Customer(String name) {
		//super();
		this.name=name;
	}	
}

class Vip extends Customer{
	int age
	public Vip() {
	//	super();
	//	age=0   无参构造中会有默认值,下面的有参构造也是有
	}
	public Vip(String name) {
		super(name);
		//String name;如果子类有个跟父类相同的属性,
		//那么如果不赋值就是默认null
		//age=0;省略了
		//name =null;省略了
	}
	
	public void shopping() {
		System.out.println(name+"正在购物"); //啥也不写默认this.name
		System.out.println(this.name+"正在购物");
		System.out.println(super.name+"正在购物");
	}
}

在这里插入图片描述
输出引用的时候会自动调用tostring方法
System.out.println(this);

super不是引用,也不保存内存地址,不指向任何对象
super只代表当前对象内部的那一块父类型的特征。

父类中私有的方法,属性,使用super也访问不了,私有的只能在本类中访问

## 面向对象的一个编程题
一个类A有一个实例变量v,从键盘接受一个正整数作为实例变量v的初始值。在创建一个类B对A类的实例变量V进行猜测

public class Caishuzi {
	public static void main(String[] args) {
		A a=new A(100);
		
		B b=new B(a);
		
		java.util.Scanner s=new java.util.Scanner(System.in);
		while(true) {
			System.out.println("请输入猜测的数字:");
			int caiceNum=s.nextInt();
			
			b.cai(caiceNum);	
		}
		
	}
}
class A{
	private int v;  //属性私有化,就要get  set

	public A() {
		
	}

	public A(int v) {
		
		this.v = v;
	}

	

	public void setv(int v) {
		this.v = v;
	}
	public int getv() {
		return v;
	}
}
class B {
	private A a;//把A作为B的实例变量,通过B猜测A ,在B对象中引用对象A
	
	
	
	public B() {
		
	}

	public B(A a) {
		
		this.a = a;
	}
	

	public void setA(A a) {
		this.a = a;
	}
	public A getA() {
		return a;
	}

	
	//猜数字的方法
	public void cai(int caiCeNum) {
		//实际数字 int shijizhi= this.getA().getV
		int shijizhi =a.getv();
		if(caiCeNum==shijizhi) {
			System.out.println("猜对了");
			//终止程序,推出jvm
			System.exit(0);
		}else if(caiCeNum>shijizhi) {
			System.out.println("猜大了");
		}else{System.out.println("猜小了");
		}
		
	}
	

	
}

设计男人类,每个男人都有身份证号,姓名,性别,女人。
设计女人类,每个女人都有身份证号,姓名,性别,男人。

public class Man {
	String name;//String是引用数据类型,
	String Id;
	static int sex=1;
	Woman woman; //数据类型有基本数据类型和引用数据类型,存的是地址指向的对象,默认Woman woman=null。
}
public class Woman {
	String name;
	String Id;
	static int sex=0;
	Man man;//女人类的男人
}

创建book类
构造方法也可以进行判断是否满足条件

public class BookTest {
	public static void main(String[] args) {
		Book b =new Book("安徒生",100);
		b.detail();
	}
}


class Book{
	private String title;
	private int pagenum;
	
	public Book(String title, int pagenum) {
		
		this.title = title;
		if(pagenum<200) {
			System.out.println("错误信息");
			this.pagenum=200;
			return;
			
		}else {
			this.pagenum = pagenum;
		}
		
		
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getPagenum() {
		return pagenum;
	}

	public void setPagenum(int pagenum) {
		if(pagenum<200) {
			System.out.println("错误信息");
			this.pagenum=200;
			return;
			
		}else {
			this.pagenum=pagenum;
		}
	}
	
	public void detail() {
		System.out.println(this.title+"这本书的页数是"+this.pagenum+"页");
	}
	
}

账户取款

public class Test2 {
	public static void main(String[] args) {
		
		Account a=new Account("1000",2000,1.23);
		Customer c=new Customer("smith",a);
		c.getA().cunqian(200);
		c.getA().quqian(100000);
	}
}

class Account{
	private String id;
	private double balance;
	private double nianlilv;
	
	
	
	public Account() {
		
	}
	public Account(String id, double balance, double nianlilv) {
		
		this.id = id;
		this.balance = balance;
		this.nianlilv = nianlilv;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}
	public double getNianlilv() {
		return nianlilv;
	}
	public void setNianlilv(double nianlilv) {
		this.nianlilv = nianlilv;
	}
	
	public void cunqian(double money) {
		balance=money+balance;
		System.out.println("成功存入: "+money+"  余额为"+balance);
		//this.setBalance(this.getBalance()+money);也可以修改余额
	}
	
	public void quqian(double money) {
		if(money<=balance) {
			balance=balance-money;
			//this.setBalance(this.getBalance()-money);
			System.out.println("成功取出: "+money+"  余额为"+balance);
		}else {
			System.out.println("余额不足,取款失败。当前余额为"+balance);
		}
	}
	
}




class Customer{
	private String name;
	private Account a;
	
	public Customer() {
		
	}

	public Customer(String name, Account a) {
		
		this.name = name;
		this.a = a;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Account getA() {
		return a;
	}

	public void setA(Account a) {
		this.a = a;
	}

}

内部类
解决不能多继承的问题
抽象类
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式
当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。

关键字static
static静态
方法实例方法,static修饰的叫静态方法
变量可分为局部变量(方法体内部声明的)和成员变量(方法体外声明的)
成员变量又可以分为实例变量和静态变量
实例方法,实例变量都是对象相关,需要先new,引用点方式访问
静态方法,静态变量都是类相关的,不需要New,采用类名点方式访问,没有空指针异常的发生
实例变量
在这里插入图片描述
静态变量存到了方法区中,节省了堆内存空间
静态代码块
static{}静态语句在类加载时候执行并且只执行一次,在main方法执行前执行。
静态代码块不常用,这种语法机制实际上是sun公司给程序员提供一个特殊的时刻/时机,这个时机叫做类加载时机

记录一下类加载的日志信息(哪年哪月哪日,哪个类加载到jvm虚拟中了)

栈:方法只要执行,就会压栈,存放局部变量
堆:new出来的对象都在队中。垃圾回收器主要针对,存放实例变量
方法区:类的信息,字节码信息,代码片段,存放静态变量

静态代码块和静态变量执行时机都一样都是在类加载时执行,先后顺序要看代码顺序.
static{
System.out.printIn("name "+ name)
}
static String name=“zhangsan”//这样是访问不了的

代码块(实例代码块)
对象构造时机

构造方法之前执行

final关键字
final管的是能不能重写,或者继承,不管可不可以调用

final修饰的局部变量一旦被赋值就不能重新赋值

final修饰的引用变量,存放的是内存地址,不能在指向另一个对象

局部变量没有初始值,main方法中的定义的是局部变量,需要手动赋值

final修饰实例变量必须手动赋上值或者看下面。
因为实例变量在构造方法的时候初始化,所以也可以在构造器上赋值

实例变量既然用final修饰了,说明实例变量不会随着对象变化而变化,所以一般加上static修饰变成静态变量节省内存,存在方法区,类加载时初始化

static final String COUNTRY=“中国”;
static final 修饰的是常量,建议全部大写,单词之间用下划线衔接,常量一般是公开的,不用private封装

类到对象是实例化,对象到类是抽象

抽象类
抽象类是非完全抽象,因为它里面的方法可以是抽象方法也可以是非抽象方法(就是带方法体的)。
抽象类是一种引用数据类型
抽象类不能实例化对象,但是有构造方法,是给子类用的

接口
接口是完全抽象的,方法都是抽象方法(不带方法体的)
接口也是一种引用数据类型,接口是特殊的抽象类。接口编译后后缀也是class
接口之间可以继承,可以继承多个继承
interface A extends B,C{},
接口中只有两种部分,常量和抽象方法如public abstract void test();
public abstract 可以省略
但是实现接口方法时的public不能省(自动生成)
接口中所有的元素都是public修饰的
接口中的抽象方法不能有方法体
常量 public static final String COUNTRY=“中国”; public static final可以省略
String COUNTRY=“中国”;
接口中随便写一个变量都是常量

接口抽象类的区别
抽象类是半抽象的,接口是完全抽象的
抽象类中有构造方法,接口没有
类只能单继承,接口可以多继承
一个类可以实现多个接口,一个类只能继承单个抽象类
接口中只允许出现常量和抽象方法
接口用的多,接口一般对行为(方法)的抽象

重写方法是修饰符只能更高不能更低,public最高?也可以多态

interface M{
    void test();
    void s();
}

class Q implements  M{

    @Override
    public void test() {
        System.out.println("这是Q类的test方法");
    }

    @Override
    public void s() {

    }
}
public class Helloworld {
    public static void main(String[] args) {
        M m =new Q();
        m.test();
    }


}

接口之间在进行强制类型转换时,接口之间没有继承关系也可以转换,但运行会出现ClassCastException异常

public class Helloworld {
    public static void main(String[] args) {
        K k =new E();
        N n= (N) k;
//应该这样写
//     if(k instanceof N){
//            N n= (N) k;
//        }
   
    }


}

interface K{
    
}
interface N{
    
}
class E implements K{
    
}

接口在开发中作用类似多态
面向抽象编程可以改为面向接口编程,接口是完全抽象的,有了接口就有可插拔,扩展力很强,不是焊死的

凡是可以使用 has a来描述的,统一以实例变量(属性)的方式存在
比如,夫妻类那个,一个类中有另一个类作为属性存在
is a设置为继承关系
like a :
cooker like a FoodMenu(厨师像一个菜单),表示为实现关系

接口都有调用者,和实现者

接口多态

public interface Menu {
    void xihongshi();
    void yuxiangrousi();
}
public class Westcook implements  Menu{

    @Override
    public void xihongshi() {
        System.out.println("西餐师傅做的西红柿炒鸡蛋");
    }

    @Override
    public void yuxiangrousi() {
        System.out.println("西餐师傅做的鱼香肉丝");
    }
}
public class Chinacook implements Menu {

    @Override
    public void xihongshi() {
        System.out.println("中餐师傅做的西红柿炒鸡蛋");
    }

    @Override
    public void yuxiangrousi() {
        System.out.println("中餐师傅做的鱼香肉丝");
    }
}
public class Customer {
    //顾客手里有一个菜单
    private Menu menu;//跟 String name;Women w;都是一样的,这里是接口

    public Customer() {
    }

    public Customer(Menu menu) {
        this.menu = menu;
    }

    public Menu getMenu() {
        return menu;
    }

    public void setMenu(Menu menu) {
        this.menu = menu;
    }
    //点菜的方法
    public void diancai(){
        //Menu menu= this.getMenu();//
        menu.xihongshi();
        menu.yuxiangrousi();
    }

}
public class test {
    public static void main(String[] args) {
        //创建厨师 顾客对象
        Chinacook chinacook=new Chinacook();

        Customer customer=new Customer(chinacook);

        customer.diancai();

    }
}

包机制
包名是:com.do.javase.Helloworld
编译:javac -d .Helloworld.java
javac 负责编译的命令
-d 带包编译
.代表编译之后的东西放到当前目录下

运行的时候:
java com.do.javase.Helloworld

improt 当类A和类B在一个包下不需要import


import java.util.Scanner;

public class TEST {

    public static void main(String[] args) {
        Scanner s =new Scanner(System.in);
        String str =s.next();
        System.out.println("你输入的字符串是:"+str);
    }
}

lang包下的直接子类不需要导入

访问控制权限
private,只能在本类中使用
protected表示只能在本类,同包,子类中访问
public,在任何地方使用
什么也不写的,默认,只能在本类以及同包下使用

简单来说public>protected(出了包如果是子类的话也可以)>默认(出了包就废了)>private

访问控制权限符修饰什么?
属性(4个)
方法(4个)
类(public 和默认)
接口(public 和默认)

object类的equals方法
通过equals方法来判断两个java对象是否相等
判断两个基本数据类型是否相等用“==”判断
int a =100;int b =100;这个"="判断a,b中保存的值是否相等
如果是两个对象t1,t2.‘=’判断的是t1,t2中保存的内存地址是否相等

object类的equals方法源代码

public boolean equals(Object obj) {
        return (this==obj);
    }

object类中的equals方法是用的等号,判断对象是否相同时要重写

class Date{
   int year;
   int month;
   int day;

    public Date() {
    }

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

//    @Override
//    public boolean equals(Object obj) {
//        //获取第一个对象的年月日
//        int year1=this.year;
//        int day1 =this.day;
//        int month1=this.month;
//        //获取第二个对象的年月日,传过来的是obj,没有这三个属性,要向下转型
//        if (obj instanceof Date){
//            Date date= (Date) obj;
//            int year2=date.year;
//            int month2=date.month;
//            int day2 =date.day;
//            if (year1==year2 && month2==month1 && day1==day2){
//                return true;
//            }
//        }
//        return false;
//    }
//改良equals方法
    @Override
    public boolean equals(Object obj) {
        //如果obj是空,直接返回false
        if(obj==null){
            return false;
        }
        //如果obj不是Date类型就直接返回false
        if(!(obj instanceof Date)){
            return  false;
        }
        //如果this和obj保存的内存地址相同,没必要比较,直接返回true
        if(this==obj){
            return true;
        }
        //程序运行到说明obj不是null,并且还是Date类型
        Date date= (Date) obj;
        if(this.year==date.year && this.month==date.month&& this.day==date.day){
            return true;
        }
        return false;
    }
}

最骚的是Idea可以自己生成重写的equals方法和tostring方法,
String也是一个类,也有构造方法,和equals方法和tostring方法等
String s=new String(“TEST”);
比较字符串的时候不能用双等号,String类已经重写了equals方法,tostring方法

基本数据类型判断用双等号
引用数据类型都用equals方法

重写equals方法要彻底

public class Test1 {
    public static void main(String[] args) {
        User u1 = new User("张三", new Address("北京", "海淀区", "111"));
        User u2 = new User("张三", new Address("北京", "海淀区", "111"));
        System.out.println(u1.equals(u2));

    }
}
 class User {
    String no;

    Address address;
    //如果用户名和地址一样就是认定一个用户

    public User() {
    }

    public User(String no, Address address) {
        this.no = no;
        this.address = address;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj==null&&!(obj instanceof User))return false;
        if (obj==this)return  true;
        User u= (User) obj;

        //address也是一个类,这里调用了address的equals方法,所以addre的equals方法也要重写
        //前面的是调用类String的equals方法,sun公司已经重写了
        if (this.no.equals(u.no)&&this.address.equals(u.address)){
            return true;
        }
        return  false;
    }
}


class Address{
    String city;
    String street;
    String zipcode;

    public Address() {
    }

    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return this.city.equals(((Address) o).city)&&this.street.equals(((Address) o).street)&&this.zipcode.equals(zipcode);
    }


}

finallize方法
源码

protected void finalize() throws Throwable { }

只有一个方法体,里面没有代码,protected修饰的,不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法
执行时机:当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用,如果希望在对象销毁时机执行一段代码的话,这段代码写在finallize方法里。
java中的垃圾回收器(GC)不是轻易启动的,垃圾太少或者时间没到,种种条件有可能启动有可能不启动

Person p=new Person();
p=null;

System.gc(); //建议启动垃圾回收器(只是建议,可能不启动,也可能启动,启动的概率增加了)

hashcode方法
源码是

public  native  int hashcode();

这不是一个抽象方法,带有native,底层调用C++程序
java对象的内存地址,经过哈希算法,得出的一个值

匿名内部类
内部类分类:
静态内部类:类似于静态变量
实例内部类:类似于实例变量
局部内部类:类似于局部变量

public class Test01 {
    //静态内部类
    static class Inner1{
    }
    //实例内部类
    class Inner2{
    }
    public void dosome(){
        int i=100;//方法体里面的变量局部变量
        class Inner3{
        }
    }
    public void doother(){
        //在这里访问不了Inner3这个类
        //如果想newInner2这个类
        new Test01().new Inner2()
    }
}

使用内部类可读性太差,能不用就不用,没有名字只能用一次

匿名内部类是局部内部类的一种

举例:

public class Test01 {
    public static void main(String[] args) {
        Mymath mm =new Mymath();
        mm.mysum(new ComputerImol(),100,200);
    }
}
//负责计算的接口
interface  Compue{
    //抽象方法
    int sum(int a,int b);

}
//调用这个方法必须有一个接口对象,但接口是不能直接new的所以写一个compute接口的实现类
class ComputerImol implements Compue{

    @Override
    public int sum(int a, int b) {
        return a+b;
    }
}

class Mymath{
    //这里第一个参数是一个引用类型,接口也是引用
    public void mysum(Compue c,int x,int y){
        int res =c.sum(x,y);
        System.out.println(res);
        }
 }

这样写表示类有名字,就是这个ComputerImol类,实现类可以不写。直接new接口后面接个大括号,里面是对接口方法的实现

public class Test01 {
    public static void main(String[] args) {
        Mymath mm =new Mymath();
        mm.mysum(new Compue(){
            public int sum(int a, int b) {
       return a+b;
    }
        },100,200);
    }
}
//负责计算的接口
interface  Compue{
    //抽象方法
    int sum(int a,int b);

}


class Mymath{
    //这里第一个参数是一个引用类型,接口也是引用
    public void mysum(Compue c,int x,int y){
        int res =c.sum(x,y);
        System.out.println(res);
        }
 }

idea修改错误alt+回车

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值