java基础学习笔记3
对象转型
父类对象引用 指向 子类对象 叫 向上转型upcasting
例如:Person a=new Student();
a只能访问Person里面的成员,而不能访问Student里面新增的成员。
把父类转化为子类,叫向下转型 downcasting
例如:Student b=(Student)a;
现在b就可以访问Student里面的成员了。
instanceof
class Person {
String name;
int age;
}
class Student extends Person {
int grade;
}
//定义两个类,一个父类一个子类
//子类 instanceof父类 true
//父类 instanceof子类 false
public class ins {
public static void main(String[] args) {
Person a = new Person();
Student b = new Student();
System.out.println(a instanceof Person); //true
System.out.println(a instanceof Student); //false
System.out.println(b instanceof Person); //true
System.out.println(b instanceof Student);//true
}
}
对象转型2
class Person {
String name;
int age;
Person(String name){
this.name=name;
}
}
class Student extends Person {
int grade;
Student(String name,int grade){
super(name);
this.grade=grade;
}
}
public class ins {
public static void main(String[] args) {
Person a = new Person("父类对象");
Student b = new Student("子类对象",97);
test(a);//打印传入的是一个普通person
test(b);//打印成绩,传入的是一个学生
}
public static void test(Person p){
if(p instanceof Student){
Student a=(Student)p;
System.out.println(a.grade);
System.out.println("传入的是一个学生");
}
else
{
System.out.println("传入的是一个普通person");
}
}
}
多态=动态绑定
执行期间,根据时间的类型调用相应的方法。
1.必须有继承关系
2.必须有重写
3.必须父类引用 指向 子类对象
举个例子:
class Person {
String name;
int age;
Person(String name){
this.name=name;
}
public void run(){
System.out.println("人在跑");
}
}
class Student extends Person {
int grade;
Student(String name,int grade){
super(name);
this.grade=grade;
}
public void run(){
System.out.println("学生在跑");
}
}
class Teacher extends Person {
String kemu;
Teacher(String name,String kemu){
super(name);
this.kemu=kemu;
}
public void run(){
System.out.println("老师在跑");
}
}
class School{
String xuexiaoname;
School(String name){
this.xuexiaoname=name;
}
public void studentRun(Person s){
System.out.println(this.xuexiaoname);
s.run();
}
}
public class duotai {
public static void main(String[] args) {
Student a=new Student("小茗同学",99);
Teacher b=new Teacher("王芳老师","教化学的");
School c=new School("希望小学");
c.studentRun(a); //打印:希望小学 学生在跑
c.studentRun(b);//打印:希望小学 老师在跑
}
}
抽象类
关键词:abstract
一个方法现目前不用实现,但需要定义出来,就用abstract修饰。
修饰以后,这个类必须加上abstract。
类加上abstract以后,凡是继承这个类,子类都必须重写这个abstract方法。除非是另一个Abstract类继承他,就不用了重写,当然,要重写也是可以的。
抽象类就是残缺的类,不能被实例化出来。
抽象类里面可以没有抽象方法。
抽象类就算里面没有抽象方法,也一样不能被实例化。
抽象类里面可以有方法的实现,子类可以通过super调用这个实现的方法。
final
修饰变量,那么这个变量的值再也不会改变。
可以在函数传参括号里面用final,局部变量不变 public void func(final int i){}
修饰方法,那么这个方法不能被重写
修饰类,那么这个类不能被继承
interface
接口 是抽象方法和常量值定义 的集合。
接口里的声明的属性默认是public static final ,也只能是他。可以不写出来!
接口里的定义的方法都是abstract,也只能是他。可以不写出来!
接口里的定义的抽象方法是默认public,也只能是他。可以不写出来!
接口里面不能写完整的方法出来。
接口 可以多重实现。
一个类实现这个接口,那么接口里面所有的方法都必须实现。
实现的时候必须加public!
interface A {
void testjiekou();
}
class B implements A
public void testjiekou(){
System.out.println("实现接口!");
}
}
public class jiekoutest {
public static void main(String[] args) {
B b =new B();
b.testjiekou();
}
}
多重实现,多态性:
interface A {
void eat();
}
interface B {
void sing();
}
class C implements A, B {
public void eat() {
System.out.println("实现A的eat接口!");
}
public void sing() {
System.out.println("实现B的sing接口!");
}
}
public class jiekoutest {
public static void main(String[] args) {
A a = new C();
a.eat();//a只能看到eat接口
C c = (C) a;//向下转型一下
c.sing();//就能看到sing接口了
}
}
异常
运行期的错误。
try尝试 catch 捕获 throw抛出
异常有很多类型,他们会被抛出来,然后我们捕获这些异常,进行相应的处理,比如,提示成中文什么的。
简单例子:
public static void main(String[] args) {
try {
int a = 4 / 0;
}
catch (ArithmeticException e){
System.out.println("被除数不能为0");
System.out.println(e);
//java.lang.ArithmeticException: / by zero
e.printStackTrace();//这个还可以显示行数
}
}
声明类时,throws可能抛出的异常
在方法中就判断什么时候throw出这个异常
finally:
无论如何都会执行,
用来进行资源的清除工作。比如:把打开的文件关闭掉。
如果继承一个类,父类有个方法throws异常,那么子类在重写这个方法时只能throws相同的异常或者干脆不抛出异常。
在try catch时,这个catch的东西一定是先小后大。
自定义异常:
写个类,继承Exception,构造函数时写spuer(message):
class MyException extends Exception {
private int id;
public MyException (string message,int id){
super (message) ;
this.id = id;
public int getid(){
return id;
}
然后在另一个类的方法中直接throws这个异常,满足异常条件就throw new 这个异常并传入参数。
一维数组
声明方式和赋值方式:
int[] a={3,4,5,6};
int b[]={5,4,5,9,8};
double[] c=new double[10];
for(int i=0;i<c.length;i++){
c[i]=i+0.1;
}
内存分布:
int数组:
引用数组:
动态初始化:数组定义 与 元素分配空间和赋值 分开操作
静态初始化:数组定义 与 元素分配空间和赋值 同时进行
对象排序
package com.ufo.five;
class Date {
int year;
int month;
int day;
@Override
public String toString() {
return "Date{" +
"year=" + year +
", month=" + month +
", day=" + day +
'}';
}
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int compare(Date d) {
return year > d.year ? 1
: year < d.year ? -1
: month > d.month ? 1
: month < d.month ? -1
: day > d.day ? 1
: day < d.day ? -1 : 0;
}
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 class datetest {
public static void main(String[] args) {
Date[] days =new Date[5];
days[0]=new Date(2020,05,17);
days[1]=new Date(2019,05,17);
days[2]=new Date(2020,07,17);
days[3]=new Date(2020,05,21);
days[4]=new Date(2018,05,17);
Date[] b=sortDate(days);
for(Date bb:b){
System.out.println(bb.toString());
}
}
public static Date[] sortDate(Date[] a) {
int len = a.length;
for (int i = 0; i < len; i++) {
for (int j = i+1; j < len-1; j++) {
if (a[i].compare(a[j]) > 0) {
Date tp = a[i];
a[i] = a[j];
a[j] = tp;
}
}
}
return a;
}
}
结果:
数三退出游戏
500个小朋友手拉手围成圈,按123123123报数,数到三的小朋友自动退出,求最后一个活下来的小朋友最开始的位置。
package com.ufo.five;
public class quit3 {
public static void main(String[] args) {
boolean a[] = new boolean[500];
for (int i = 0; i < a.length; i++) {
a[i] = true;
}
int leftcount = a.length;
int countNum = 0;
int index = 0;
while (leftcount > 1) {
if (a[index] == true) {
countNum++;
if (countNum == 3) {
countNum = 0;
a[index] = false;
leftcount--;
}
}
index++;
if (index == a.length) {
index = 0;
}
}
for (int i = 0; i < a.length; i++) {
if (a[i] == true) {
System.out.println(i);
}
}
}
}
//答案435