方法重载(Overload)
1.定义:完全不同的方法,但是名称都相同并且与类名一致。
2.构成重载的条件:
(1)形参类型,形参个数,形参参数类型顺序不同
例如
public class Animal{
private int age;
private String color;
//重载方法
public Animal(){
System.out.println("我是动物");
}
public Animal(int age){
System.out.println("我8岁了");
}
public Animal(int age,String color){
System.out.println("0.0");
}
public Animal(String color,int age){
System.out.println("QAQ")
}
}
方法重写(Override)
1.定义:子类重写父类的方法,子类通过重写父类的方法,可以用自身的行为替换父类的行为
2.方法的重写需要符合下面三个要点:
(1)方法名,形参列表相同
(2)返回值类型和声明异常类型,子类小于等于父类
(3)访问权限,子类大于等于父类
(4)final,private,static修饰的方法不能重写。
3.示例代码
输出结果:
Dog is running
animal is running
抽象类/方法(abstract关键字)
1.相关知识点:
(1)抽象方法没有方法体,有抽象方法的类必须定义抽象类
(2)通过子类重写,子类必须重写,抽象方法父类没有实现,子类必须实现
(3)抽象类不能实例化,不能new来实例化抽象类,可以new子类来实现
(3)抽象类可以包含属性,方法,构造方法,但是构造方法不能用来new实例。
(4)抽象类只能用来被继承,抽象方法必须被子类实现
例如:有Employee类,Student类,Person类,Person类为其余两个类的父类,这三个类中都有一个getDescription方法,他可以返回对一个人的简述,Employee类和Student类实现这个方法是很容易的,但是Person类对这两个类是一无所知的,因此我们引入了抽象类。
2.示例代码
package com.hdu;
//定义父类
public abstract class Person {
public abstract String getDescription();
private String name;
public Person(String name){
this.name=name;
}
public String getName(){
return name;
}
}
package com.hdu;
//定义子类
public class Student extends Person {
private String major;
public Student(String name,String major){
super(name);//调用父类构造方法
this.major=major;
}
@Override
public String getDescription(){
return "a student majoring in" +major;
}
}
package com.hdu;
/**
* abstract关键字可以将父类不能调用的子类方法,进行调用。
*/
public class PersonTest {
public static void main(String[] args) {
Person [] people=new Person[1];
people[0]=new Student("wyx","computer science");
for(Person p:people){
System.out.println(p.getName()+","+p.getDescription());
}
}
}
输出结果:
wyx,a student major in computer science
Object类:所有类的父类
1.Object类可以引用任何类型的对象
例如:Object obj=new Emploee;
2.equals方法:用于检测一个对象是否等于另一个对象()
(1)equals方法与==的区别 :==表示比较双方是否相同,如果是基本类型则表示值相等,如果是引用类型(类,数组,接口)则表示地址相等。
equals方法:对象内容是否相等的逻辑 u1.equals(u2)
(2)重写equals方法的逻辑(根据某一固定属性来进行判断):首先,判断equals前的对象与object对象是否相同,之后,判断传入的object是否为空,其次,判断两个对象是否为同一类型,最后,强制转换传入的Object对象
(3)重写equals方法的示例代码:
public boolean equals(Object otherObject) {
if (this == obj)//判断是不是同一个对象
return true;
if(otherObject==null)//判断传入的对象是否为空
return false;
if(getClass()!=obj.getClass())//比较二者来自为同一个类
return false;
User other=(User)obj;//强制转换为相应类型的类
if(id!=other.id)//根据id来判断两个对象是否相等
return false;
return true;
如果在子类中重新定义equals,就要在其中包含一个super.equals(other)调用
3.重写toString方法:
(1)如果不重写toString方法时打印对象时会打印出对象的地址:System.out.println(对象.toString());
(2)重写toString方法 :
public String toString(){
public String toString(){
return "测试Object对象"
}
}
(3)重写equals和重写toString的示例代码:
package com.hd.inheritance;
import java.time.LocalDate;
public class Employee {//Employee类
private String name;
private double salary;
private LocalDate hireDay;
//构造方法
public Employee(String name,double salary,int year,int month,int day){
this.name=name;
this.salary=salary;
hireDay=LocalDate.of(year,month,day);
}
public String getName(){
return name;
}
public double getSalary(){
return salary;
}
public LocalDate getHireDay(){
return hireDay;
}
public void raiseSalary(double byPercent){
double raise=salary*byPercent/100;
salary+=raise;
}
@Override
public boolean equals(Object otherObject){
if(this==otherObject)//判断两者是否为同一对象
return true;
if(otherObject==null)
return false; //判断传入的对象是否为空
if(getClass()!=otherObject.getClass())
return false; //判断两者属于同一类
Employee other=(Employee)otherObject;
if(name!=other.name)
return false;
return true;
}
@Override
public String toString(){
return getClass().getName()+"[name="+name+",salary="+salary+"hireday="+hireDay+"]";
}
}
package com.hd.inheritance;
public class Manager extends Employee {//Manager类
private double bonus;
public Manager(String name, double salary, int year, int month, int day) {
super(name, salary, year, month, day);
bonus = 0;
}
@Override
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary+=bonus;
}
public void setBonus(double bonus){
this.bonus=bonus;
}
@Override
public boolean equals(Object otherObject){
if(!super.equals(otherObject))
return false;
Manager other=(Manager)otherObject;
return bonus==other.bonus;
}
@Override
public String toString(){
return super.toString()+"[bonus="+bonus+"]";
}
}
package com.hd.inheritance;
public class EqualsTest {//测试类
public static void main(String[] args) {
Employee alice1=new Employee("a",75000,1999,04,18);
Employee alice2=alice1;
Employee alice3=new Employee("a",75000,1999,04,18);
Employee bob=new Employee("b",5000,1989,10,1);
System.out.println(alice1==alice2);
System.out.println(alice1==alice3);
System.out.println(alice1.equals(alice2));
System.out.println(alice1.equals(bob));
System.out.println(bob);
Manager carl=new Manager("c",80000,1999,12,15);
Manager boss=new Manager("c",80000,1987,12,15);
boss.setBonus(5000);
System.out.println(boss);
System.out.println(carl.equals(boss));
}
}
测试结果:
内部类
内部类的分类:成员内部类(非静态内部类,静态内部类),匿名内部类,局部内部类。
1.成员内部类:可以使用private,default,protected,publicj进行修饰
(1)内部类定义到外部类里面的好处:内部类可以直接使用外部类的属性和方法
(2)非静态内部类(实例代码):
public class TestInnerClass{
publicstatic void main (String [] args){
//创建内部类对象
Outer.Inner inner=new Outer().new Inener();
inner.show();
}
}
class Outer{
private int age=10;
public void testOuter(){
class Inner{//若为静态内部类,class前面加static
int age=20;
public void show(){
int age=30;
System.out.println("外部类的成员变量"+Outer.this.age)
System.out.println(“内部类的成员变量”+this.age);
System.out.println("局部变量age"+age);
}
}
}
}
总结:1.非静态内部类必须寄存在一个外部类的对象里
2.非静态内部类可直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员,这样可以实现良好的封装。
3.非静态内部类不能有静态方法,静态属性和静态初始化块
4.外部类的静态方法,静态代码块不能访问非静态内部类
5.成员变量的访问要点:
(1)内部类里方法的局部变量:变量名
(2)内部类属性:this.变量名
(3)外部类属性:外部类名.this.变量名
2.(1)静态内部类(不依托于外部对象):静态的内部类中不能访问外部类中非静态的变量和方法。
(2)静态内部类调用外部静态变量:外部类名.变量名
public class TestStaticInnerClass {
public static void main(String[] args) {
Out.newInner newInner=new Out.newInner();
newInner.add();
}
}
class Out{
private static String name="aa";
static class newInner{
int salary=2000;
public void add(){
int salary=500;
System.out.println("访问静态外部类变量"+Out.name);
System.out.println("访问静态内部类变量"+this.salary);
System.out.println("访问局部变量"+salary);
}
}
}
运行结果:
3.匿名内部类(适合那种只需要使用一次的类)
理解:只需要创建这个类的一个对象,甚至不需要为类指定名字
package com.hdu;
import javax.swing.plaf.synth.SynthSpinnerUI;
public class SpecialInnerClass {
public static void test(AA a) {
a.aa();
}
public static void main(String[] args) {
SpecialInnerClass.test(new AA() {
@Override
public void aa() {
System.out.println("i love code");
}
});
}
}
interface AA {
void aa();
}
super关键字
(1)super关键字用法;永远位于构造方法的第一句
(2)super是直接父类对象的引用,可以通过super来访问父类中被子类覆盖的方法或属性
(3)super.对象或方法 //调用父类的对象或方法,顺序是先调用父类,再子类,
(4)super.方法不放在主类里,放在对应继承重写方法里的语句块里
(5)构造方法的调用程序,构造方法第一句总是:super()来调用父类对应的构造方法
接口(interface)
1.接口中包含:方法(抽象方法,无需写abstract),常量(无需写final)
2.定义接口格式:【访问修饰符】interface 接口名【extends 父接口1,父接口2】
3实现接口:implements关键字(实现接口时,必须把方法声明为public)
例如:class Emlpoyee implements Comparable
示例代码:
public interface MyInterface {
int MAX_AGE=100;//默认常量
void test01();//默认抽象类
}
class MyClass implements MyInterface{
@Override
public void test01(){ //实现抽象方法
System.out.println("****");
}
}
class salary{
public static void main(String[] args) {
MyClass m=new MyClass();
m.test01();
}
}
注:new Angel时,我把他归到了Volant类,意味着Angel能调用Volant的接口中的内容,并不能调用Honest中的内容。
package com.hd.inheritance;
public class TestInterface {
public static void main(String[] args) {
Volant volant=new Angel();
volant.fly();
System.out.println();
Volant volant1=new BirdMan();
volant1.fly();
}
}
/**
* 飞行接口
* @author Adiministator
*/
interface Volant{
int FLY_HIGHT=100;
void fly();
}
interface Honest{
void helpOther();
}
class Angel implements Volant,Honest{
@Override
public void fly(){
System.out.println("我是天使,飞起来了");
}
@Override
public void helpOther(){
System.out.println("扶老奶奶过马路");
}
}
class GoodMan implements Honest{
@Override
public void helpOther(){
System.out.println("扶老奶奶过马路");
}
}
class BirdMan implements Volant{
@Override
public void fly(){
System.out.println("我是鸟人");
}
}
异常
1.java采用面向对象的方式来处理异常
2.异常机制(Exception)
处理过程:(1)抛出异常:如果发生异常,将这个异常封装成对象,递交给JRE(虚拟机)
(2)捕获异常
3.异常分类
所有异常的根类 Throwable,分为Error 和exception
exception包括RuntimeException运行时异常和CheckedException(已检查异常)
RuntimeException运行时异常(多时逻辑出现错误引起)
4捕获异常try/catch
若语句1有异常,语句2无异常,那么语句以自动匹配相应的catch,最终执行finally,而并不执行语句2
catch中子类Exception在父类Exception前
格式:
try{ 语句1://假如语句1有异常
语句2:
}
catch(Exception1 e){
e.printStackTrace();//打印异常信息
}
catch(Exception2 e){
}
finally{
//不管是否碰到异常,都需要执行finally
}
CheckedException(编译时就报错出现异常)
6.thows(直接抛出异常,谁调用谁处理) 调用时可以trycatch,也可以throws给main方法,main方法抛给JRE 4
7.自定义异常(throw)
(1)自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理,
如果继承RuntimeException类则不需要处理
(2)自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。
(3)继承RumtimeException示例代码:
package opp.java;
public class Test4 {
public static void main(String[] args) {
Person p=new Person();
p.setAge(-10);
}
}
class Person{
private int age;
public void setAge(int age){
if(age<0){
throw new IligalAgeException("年龄不能小于0");
}
this.age=age;
}
public int getAge(){
return age;
}
}
class IligalAgeException extends RuntimeException{
public IligalAgeException(){//空构造器
}
public IligalAgeException(String msg){//带形参构造器
super(msg);
}
}
(4)自定义异常类继承Exception的示例代码:(编译时出现错误,使用try-catch或者直接throws抛出)
package opp.java;
public class Test4 {
public static void main(String[] args) {
Person p=new Person();
p.setAge(-10);
}
}
class Person{
private int age;
public void setAge(int age){
if(age<0){
try {
throw new IligalAgeException("年龄不能小于0");
} catch (IligalAgeException e) {
e.printStackTrace();
}
}
this.age=age;
}
public int getAge(){
return age;
}
}
class IligalAgeException extends Exception{
public IligalAgeException(){
}
public IligalAgeException(String msg){
super(msg);
}
}
容器
容器(集合)
1.数组就是一种容器,可以在其中放置对象或基本类型数据
数组优势:访问速度快,效率高
数组劣势:不灵活。容量需要事先定义好,不能随着需求的变话而扩容
2.容器:接口Collection包括Set(无顺序不可重复),List(有顺序,可重复)
Set包括 HashSet
List包括ArrayList,LinkedList(链表)
接口Map 用HashMap实现
3.泛型(Generic):相当于在容器上贴标签,假如我贴上羊肉的标签,我往容器中放入的全是羊肉,取出来也都是羊肉
(1)泛型的本质就是“数据类型的参数化”。
可以把泛型理解为数据类型的一个占位符(形参)
调用泛型时必须传入实际类型
(2)在类声明后面增加泛型列表<T,E,V>
Class Collection//表示传进来类型E
(3)代表传进来的类型
(4)创建对象时,需要在规定数据类型
MyCollection mc = new MyCollection();
//E相当于形参,String相当于实参
示例代码
package cn.wyx;
public class Generic {
public static void main(String[] args) {
Option <String> o=new Option<>();//实参,相当于把Option类标注成String类型
o.set("wyx",1);
System.out.println(o.get(1));
}
}
class Option<E>{ //形参
Object [] objs =new Object[5];
public void set(E e,int index){//把Object obj 替换为 E e
objs[index]=e;
}
public E get(int index){
return (E) objs[index];
}
}
运行结果:wyx
4.Collection接口,List接口
Collection c=new ArrayList();
方法c.size() //判断里面有多少元素
方法c.isEmpty();//判断是不是空的,返回boolean
方法c.add(“giao”)//添加一个元素,打印c时默认调用toString方法
方法c.remove(“高老二”)//移除元素,并不是删除,只是把对象移除到容器外
方法c.clear();//移除容器内所有元素
方法c.toArray();//转化成object数组
例如:Object[] obj=c.toArray();
方法c.contains(“高老二”);//查看对象里是否包含高老二
示例代码如下:
package cn.wyx;
import java.util.ArrayList;
import java.util.Collection;
/**
* 测试Collection
*/
public class Test01 {
public static void main(String[] args) {
Collection <String> c=new ArrayList<>();
System.out.println(c.isEmpty()); //判断是否为空
c.add("wyx"); //添加元素
c.add("fyy");
System.out.println(c.size());//查看当前对象中有几个元素
c.remove("fyy");//从容器中移除元素,并不是删除,只是把对象移除到容器外
System.out.println(c);//可以直接打印,因为里面默认有toString方法
Object [] objects=c.toArray();//转换成Object数组
System.out.println(objects);
System.out.println(c.contains("wyx"));//查看对象是否包含某一元素
c.clear();//删除容器中所有元素
System.out.println(c);
}
}
运行结果:
5.ArrayList
(1)声明:List list01=new ArrayList<>();
(2)方法a.addAll(Collection c);//将c容器里所有的元素增加到a容器里
(3)方法a.removeAll (Collection c);//移除a容器和c容器中共同的元素,只移除本容器中
方法a.retainAll(Collection c);在a容器中保留a,c容器的交集元素,其他移除
(4)方法a.containsAll(Collection c);a容器是不是包含另一个容器的所有元素,是返回True
示例代码
package cn.wyx;
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
public static void main(String[] args) {
List<String> list1=new ArrayList<String>();//声明list1
list1.add("a");//添加元素
list1.add("b");
List<String> list2=new ArrayList<String>();//声明list2
list2.add("a");
list2.add("c");
System.out.println(list1);
System.out.println(list2);
list1.addAll(list2);//将list2中所有元素添加到list1中
System.out.println(list1);
list1.removeAll(list2);//移除list1容器和list2 容器中共同的元素,只移除本容器中
System.out.println(list1);
list1.add("c");
list1.retainAll(list2);//在list1容器中保留list1,list2容器的交集元素,其他移除
System.out.println(list1);
System.out.println( list1.containsAll(list2));
}
}
运行结果
6.ArrayList索引和顺序相关方法
(1)List是有序,可重复的容器。
有序:相当于数组的索引
可重复:可加入重复元素,List通常满足equals方法,返回true
(2)List接口常用实现类:ArrayList,LinkedList和Vector
ArrayList,Vector底层实现是数组,LinkedList底层是链表
(3)List方法
插入元素方法:add(索引,元素)
删除元素方法 :remove(索引)
设置方法:set(索引,“元素”)//把索引处的元素替换掉,相当于修改
得到方法:get(索引)//返回索引处元素
返回索引:indexOf(”元素“)//不包含元素返回-1,若有两个相同元素,则从左往右开始,获取第一个元素的索引
lastIndexOf(”元素“)获取该元素顺序从右往左开始,数索引从左往右
示例代码:
package cn.wyx;
import java.util.ArrayList;
import java.util.List;
public class Test05 {
public static void main(String[] args) {
parcel();
}
public static void parcel(){
List<String> list=new ArrayList<>();
list.add("wyx"); //添加元素
list.add("zzh"); //添加元素
list.add("wjw"); //添加元素
System.out.println(list); //打印list对象
list.add(1,"qaq");//插入元素
System.out.println(list);
System.out.println(list.get(3));//根据索引返回元素
System.out.println(list.indexOf("zzh"));//不包含元素返回-1,若有两个相同元素,则从左往右开始,获取第一个元素的索引
list.add("wyx");
System.out.println(list);
System.out.println(list.lastIndexOf("wyx"));//获取该元素顺序从右往左开始,数索引从左往右
}
}
运行结果:
7.Map接口—HashMap常用方法
(1)Map用来存储键(key)值(value),通过键对象,可以找到值对象
(2)键可以是任意类型的对象,相当于将数组里索引功能扩大
(3)定义Map:Map<Integer,String> m1=new HashMap<>();
//Integer为键的类型,String为值的类型
(4)添加键值对:put方法:m1.put(1,“one”)//存储时把1和one关联起来,成对存放
(5)取键值对:get方法:m1.get(index)//取出value
(6)删除键值对:remove:m1.remove(Object key);
(7)包含键值对的数量: size()
(8) 查看Map是否为空: isEmpty()
(9)清空map对象所有键值对:void clear()
(10) 将t中所有键值对放到本map对象:void putAll(Map t)
(11)Map容器中是否包含键对象的键值对:boolean containKey(Object key)
(12)Map容器中是否包含值对象对应的键值对:boolean containValue(Object value)
(13)键对象不能重复,若重复,则新的覆盖旧的
(14)打印方法直接返回Map中内容
示例代码:
package cn.wyx;
import java.util.HashMap;
import java.util.Map;
public class TestMao {
public static void main(String[] args) {
Map<Integer,String> map =new HashMap<>();
map.put(1,"one");
map.put(2,"two");
map.put(3,"three");
System.out.println(map);//打印
System.out.println(map.get(1));//取出1对应的value
System.out.println(map.size());//打印map中有多少键值对
System.out.println(map.isEmpty());//判断Map容器是否为空
System.out.println(map.containsKey(2));//Map容器中是否包含键对象的键值对
System.out.println(map.containsValue("four"));//Map容器中是否包含值对象对应的键值对
}
}
运行结果:
示例代码:
import com.hd.inheritance.Employee;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) {
Employeement e1=new Employeement(1001,"小王",2000);
Employeement e2=new Employeement(1002,"小赵",6000);
Employeement e3=new Employeement(1003,"小风",8000);
Employeement e4=new Employeement(1001,"小狗",100000);
Map<Integer,Employeement> map=new HashMap<>();
map.put(1001,e1);
map.put(1002,e2);
map.put(1003,e3);
map.put(1001,e4);
Employeement em=map.get(1001);
System.out.println(em.getName());
}
}
class Employeement{
private int id;
private String name;
private double salary;
public Employeement(int id,String name,double salary){
super();
this.id=id;
this.name=name;
this.salary=salary;
}
public void setId(int id){
this.id=id;
}
public int getId(){
return id;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setSalary(double salary){
this.salary=salary;
}
public double getSalary(){
return salary;
}
public String toString(){
return "id:"+id+"name:"+name+"salary"+salary;
}
}
运行结果:小狗
15 .TreeMap使用(一般key和value需要排序时使用)
(1)底层原理:红黑二叉树
(2)特点:内部做排序,按照key递增的方式排序,利用增强for循环来实现Comparable接口(用于按什么排列),keySet()可以返回key的值
(3)示例代码
import java.util.Map;
import java.util.TreeMap;
public class TestTreeMap {
public static void main(String[] args) {
Map<Integer,String> map=new TreeMap<>();
map.put(22,"aa");
map.put(1,"bb");
map.put(15,"cc");
for(Integer a: map.keySet()){
System.out.println(map.get(a));
}
}
}
运行结果
bb,cc,aa
16.Iterator迭代器(遍历容器元素)
(1)List和set相同
1.先定义空类型方法,建立集合对象,添加元素
hasNext()//判断有没有下一个
2.定义迭代对象,利用for循环:Iterator iter =集合对象.iterator();iter.hasNext();
3.循环内容:既返回当前指向的对象,又将标记指向下一个对象,String temp=iter.next,打印
示例代码:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TestIterator {
public static void main(String[] args) {
Test01();
}
public static void Test01(){
List<String> list=new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
for(Iterator <String> iter=list.iterator();iter.hasNext();){
String temp=iter.next();//返回当前对象,并指向下一个对象
System.out.println(temp);
}
}
}
(2)map
获得键的集合,存放在Set集合中,利用keySet()方法 Set keySet=map1.keySet();
import javax.swing.plaf.synth.SynthSpinnerUI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestIteratorMap {
public static void main(String[] args) {
Test02();
}
public static void Test02(){
Map<Integer,String> map =new HashMap<>();
map.put(1,"pp");
map.put(2,"qq");
map.put(3,"dd");
Set<Integer> set= map.keySet();//获取键对象
for(Iterator<Integer> itera = set.iterator();itera.hasNext();){
Integer key=itera.next();返回键对象,并指向下一个对象
System.out.println(map.get(key));
}
}
}
17.Set接口(无顺序,不可重复)
实现类:HashSet(底层用HashMap,添加元素相当于添加Map中的key,Value是默认你对象)
TreeSet(底层用TreeMap实现,按照 元素自增的方式排序,自定义排序利用comparable接口)
public int compareTo(形参)<泛型>
``