大学时的java不傻瓜笔记-1

第一课碎碎念

  • C语言是JAVA语言的语法基础,学过C语言就能看懂基本JAVA语言程序
  • Android是利用Java开发的,Java中的大部分可以在Android中运行
  • Android不是一门语言,而是一种操作系统

基础概念

正数的补码就是其本身,负数的补码就是取反。
栈,数据结构,先进后出。
队列,先进先出。

一个程序只有运行结束才会退出来

float a=1.2f;
double b=1.2345d;
a=(float)b;
int d,c=5;
d= c++; //d=5,c=6
d= ++c; //d=6,c=6

条件取反的时候,or和and要相互转换。

异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。

if (a>b?a=10:a=100);

for循环在没有循环的时候就知道会循环多少次,在不知道要循环多少次的时候使用while。

Java:OOP面向对象的程序设计。
C面向过程。
面向对象的思想,以装潢为例,就是寻找电工,泥瓦匠等工作人员,面向过程则是对于装潢中的各个步骤。

学习Java基本概念一定要很清楚

Java类
类(抽象的)是相关数据与方法的(抽象)集合。
对象(具体的)该类的实例。
命名要用驼峰法,要有意义,最好使用英文。

  • 类名
  • 字段
  • 方法

类的名称大写开头,字段的名称小写开头
语句只能出现在方法内

class 类名{
    int 字段;
    void 方法名(形参){
        语句;//这就是方法
        //方法中有,方法名,形参,返回值return(void没有)
    }
}

字段和变量很像 但是字段处于类下面,而变量在方法下。在eclipse中,字段会标蓝
实例化 将一个抽象的类具体到一个对象上

新建类和构造方法

步骤就不放了,我要是哪一天点击什么菜单都想不起来也查不到的话,不如早日改行XD

package app04.myself;

public class Students {
	public String namber;
	public String name;
	public String age;
	
	public void display() {
		System.out.println("学号:"+this.namber);
		System.out.println("姓名:"+this.name);
		System.out.println("年龄:"+this.age);
	}
}

构造方法没有返回值,方法名和类名一样

public Students(String namber, String name, int age) {
    super();
    this.namber = namber;
    this.name = name;
    this.age = age;
}

构造方法在new的时候,会自动调用

Students xxx=new Students("12334","xxx",20);

再创建一个无参的构造方法。如果本身不写有参构造方法,系统会自动写一个无参构造方法,但是如果我们写了有参构造方法,系统就不会自动写一个无参构造方法。有时子类会用到无参。
Java 程序在执行子类的构造方法之前,如果没有用 super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。

详细查阅书本P39,如果想不起来书放在哪里了就看一看书桌左侧的柜子(柜子,不是抽屉(换地方了记得来改

内存分为两块,栈和堆,基本变量放在栈里。

封装

包是用来分类放置类的。
面向对象的程序设计的特点:封装、继承、多态

如果一个类相当于一个银行,存钱的时候钱存在什么地方-知道一个存取的方法,但不知道具体存钱的地方细则-这就是封装(留下方法,屏蔽细节)。
封装的第一步,字段内部可见外部并不可见,private 在本类中可以调用,其他类中看不见 ,字段变成私有。
封装第二步,public的方法可以在其他类当中使用。

//修改名字
public void steName(String name)
{
this.name=name;
}
//取
public string getName()
{
return this.name;
}

优点:屏蔽复杂度,方便升级

多态

多态(overload重载,override覆盖)

覆盖是多态(可能有误 没听清楚)

重载,一部分理论认为重载不属于多态,一部分认为重载属于多态。
在同一个类中,允许一个方法的名称相同,但是参数的类型个数不同。
返回值不能作为区分重载不同方法的要素。
构造方法也可以重载。

一般构造方法的时候会给一个没有参数的重载(?讲子类的时候细讲)

有返回值的方法不复制,程序也可以允许。

垃圾收集,销毁不再使用的对象并释放内存,不再使用的对象定义为那些不再被引用的对象,或者其引用已经超出作用域的对象。
中没有被中的地址指向的就是垃圾。
字符串不断赋值的时候,会把原先的值变成垃圾。

继承

覆盖发生在父类和子类之间

extends,扩展,继承是类实现扩充的一个方法。

package app07;
class Animal {
    public float weight;
    public void eat() {
    }
}

class Bird extends Animal {	
	//Bird是Animal的子类,Animal是Bird的父类(超类)
	//Animal中可以继承的字段方法他都有,同时还具有单独属于Bird的字段方法
    public int numberOfWings = 2;
    public void fly() {
    }
}

class Fish extends Animal {
    public int numberOfFins = 2;
    public void swim() {
    }
}

class Dog extends Animal {
    public int numberOfLegs = 4;
    public void walk() {
    }
}

子类反过来也可以扩展,除非他是final使得它不能扩展。
所有Java类都不用显式地扩展一个父类,而是会自动继承了java.lang.Object类(是所有类的父亲(自动))。
在Java中,一个类只能有一个父类,不能访问父类的私有方法,在一个包中的时候可以访问default方法。

方法覆盖
子类重写(方法的名称、参数、返回值都一样,功能不一样)父类已经有的办法
父类的方法依旧存在,只是在子类中调用的时候不会调用到父类的方法

package app07;
public class Box {
    public int length;
    public int width;
    public int height;

    public Box(int length, int width, int height) {
        this.length = length;
        this.width = width;
        this.height = height;
    }

    @Override  //覆盖 父类中一定要有下面写到的方法
    public String toString() { //方法不变,但程序内容会改变
        return "I am a Box.";
    }

    @Override
    public Object clone() {
        return new Box(1, 1, 1);
    }
}

访问控制符

控制访问范围

同一个类 同一个包 不同包的子类 所有
private
default(不写)
protected
public

如果方法是private,也就说方法只能在本类当中的其他方法中调用。

this关键字

在引用当前对象的任何方法或构造方法时使用this(在本类中代表本类对象)为了区分相同的对象名和本类名。

在类中使用其他类,很常见 。
当使用的类在一个包,默认允许。
使用包以外的类需要import。
写在package后面。

final变量

如果一个字段一旦赋值不能再变,常量。

final  类型 变量名(字段名)=赋值;

静态成员static

不需要new可以直接调用

内存从两块栈和堆变成三块:

  1. 栈(程序,变量,速度最快)
  2. 堆(最大的空间,new的东西,对象对应的具体的值(通过在栈中对象的地址访问),处理速度慢)
  3. 源空间 第三部分暂时成为 静态区域 放稳定常用的东西

static静态字段名称会变成斜体,会直接放在静态区域,以 类名.名称 0(0是它的值)的方式存放。

在静态所在的类没new之前也可以调用静态

调用方式 方法(类名.名称);   类.名称=赋值;

无论类new了几次,一个静态始终只有一个(字段)共用
直接调用方法的好处:方便,最常用的方法static可以直接调用(静态方法)。

老师:从今天开始你们脑袋里面要有三块区域咯!
我:从今天开始我的脑袋要开始头晕啦!

静态方法也被成为类方法,不是静态的方法叫对象方法(使用对象调用)。

从一个静态方法的内部不能调用实例方法或者实例字段,因为实例需要new,而静态没有new,所以调用的时候实例没有地方存放,也就说当时没有这个实例。

在一个静态方法中可以直接调用其他静态。

静态final变量,不需要new的常量。

子类父类的强制转换

所有子类的对象都可以赋给超类对象。
向上强制转型 upcasting(安全)将子类的对象强制转型为父类的对象
可以把子类覆盖父类的方法带上去

//假设Child是Parent的子类
Child child = new Child();
Parent parent = child;

parent引用变量的时候不能访问那些只能在Child中可以使用的成员。
在父类中引用的子类对象可以强制转回子类,向下强制转换 downcasting(不安全:从哪儿来回哪儿去)。

超类强制转换为子类。向下强制转换只能转回对象本身所在的子类当中
只有当父类的引用已经指向子类的一个实例的时候,才允许将子类向下强制转型

Child child = new Child();
Parent parent = child;
Child child2=(Child)parent;

final类,类不能继承
final方法,方法不能被覆盖
final字段,字段不能改动

instanceof操作符

测试一个对象是否是一个特定的类型(查看对象是否存在于选定的类里)。

if(objectReference instanceof type)

实例:

//if会返回true
String s = "Holle";
if(s instanceof java.lang.String){}
//if会返回falseString s = null;
if(s instanceof java.lang.String){}
//例如 Child是Parent是子类
Child child = new Child();
if(child instanceof Parent){}//会返回true

这个关键字在向下强制转换的时候判断对象属于哪个子类很有用

语法上没有错误不代表语义上没有错误,语法在编译阶段没有错误,但是在运行时会因为语义错误无法执行。

调用超类的隐藏方法
超类的隐藏方法:超类中被覆盖的方法

接口和抽象类

接口(interface),基类,抽象类

类 extends 类

类 implements 接口1,接口2

接口 extends 接口1,接口2

接口

package app10;
public interface Printable { //接口
    public void print(Object o); //抽象方法 表示定义了一个print的方法,但是没有特地的方法
}

抽象方法有方法名,参数定义,返回值定义;没有功能实现。(如果后面不是“;”而是{}则表示为空的功能,是有功能的。)抽象 abstract
接口是“规范” 是服务提供者和服务使用者之间的协议。
比如,不同地区银行的利息算法都不一样,但是总行设定好了计算利息的方法名,参数,返回值,支行所使用计算利息的方法都使用总行制定好的规范。
接口可以通过子类继承去覆盖方法产生功能。

编程在顶层不知道细节但是需要规范的时候,都可以使用接口。


implements 实现
Printable是接口print存在的接口 ↑
CanonDriver是↓这个类

package app10;
public class CanonDriver implements Printable {
    @Override
    public void print(Object obj) {
        System.out.println("this is CanonDriver");// code that does the printing
    }
}

子类可以/不可以覆盖父类,子类必须覆盖接口才可以使用。
抽象方法在子类中被覆盖。
有了接口 底下所有的方法都会按照相应的名字去设定方法。

接口中的字段必须初始化(有初值),必须是(隐式的)公有的public、静态的static、final的
隐式-即使不声明也会是这三种状态。
接口中的字段也属于规范,任何方法都可以直接调用且不可更改。
接口中什么时候添加字段?在需要发布一些大家通用的参数情况下,接口中才会添加字段。
在接口中,如果两个字段拥有相同的名称会发生编译器错误,但是接口可以从其超接口继承多个具有相同名称的字段。

接口一旦发布,就不能添加新的方法,否则已经发布的版本就会报错。
接口的扩充不允许向上不兼容。
接口支持继承extends,接口的升级只能用继承。目的:为了安全地给一个接口添加功能,而不会破坏原有的代码。接口允许一次继承多个接口。

程序必须向上兼容

接口中的默认方法,如果扩展所有的接口,可能会导致接口的数目倍增,而且接口可能产生奇怪的名字。
JDK 1.8 以后,接口中可以添加默认发放(例如功能为空{ } 的方法,使用时进行覆盖)接口的默认方法是带有实现的方法,实现了接口的一个类,不一定必须实现默认方法,这意味着可以给接口添加新的方法而不会引起向后兼容的问题。

为了让接口中的方法成为默认方法,default关键字不可以省略,并且不是使用“;”结束 ,而是{ }

接口中的静态方法 可以使用接口名.静态方法名 Java 8 之后,接口中可以带有静态的方法,以便和接口相关的所有静态方法都可以写入接口。需要加上关键字static,默认公有。

基类

实现类必须覆盖接口中的所有抽象方法,当只需要其中一部分方法时可以创建一个泛型的实现类,它使用默认代码覆盖了接口中的抽象方法,然后一个实现类可以扩展这个泛型类,只需要覆盖想用的方法。
基类实现接口,覆盖的抽象方法功能为空。实现类继承基类,对于自己要使用的方法进行覆盖。
目的:减少用户代码量。

抽象类

一个类中同时包含抽象方法,abstract和非抽象方法。
类要携带 abstract关键字,类中的抽象方法需要携带 abstract关键字。
类要携带 abstract关键字 类中的抽象方法需要携带 abstract关键字。

实例

People类

package test1;

/**
 * 1.基本类的设计,包含字段方法 2.方法的重载overload(两个speech) 3.封装,Source-Getters and setters
 * 4.构造方法,有参/无参 Source-Fields 5.无参留给子类
 */
public class People {
	private String name; // 姓名
	private int age; // 年龄
	private String gender; // 性别

	public People(String name, int age, String gender) {
		// super();调用超类的无参
		this.name = name;
		this.age = age;
		this.gender = gender;
	}

	public People() {
		super();
	}

	public void speech() {
		System.out.println("People speech");
	}

	// 重载
	public void speech(String s) {
		System.out.println(s + ":People speech");
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
}

Student类

package test1;

/**
 * 1.完成Student对People的继承,Student可以访问People的字段 2.静态字段,记录学生总数 3.在构造方法中,添加People的参数
 * 4.覆盖方法 soure-Override 5.覆盖InterfaceShow接口中的display抽象方法
 */
public class Student extends People implements InterfaceShow {
	private String number; // 学号
	private int avg; // 平均成绩
	public static int studentTotal = 0; // 在构造方法中添加

	public Student() {
		studentTotal++;
	}

	public Student(String name, int age, String gender, String number, int avg) {
		super(name, age, gender);
		this.number = number;
		this.avg = avg;
		studentTotal++;
	}

	@Override
	public void speech() {
		System.out.println("Student speech");
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public int getAvg() {
		return avg;
	}

	public void setAvg(int avg) {
		this.avg = avg;
	}

	@Override
	public void display() {
		System.out.println("【学生】\n姓名:" + this.getName() + "\t年龄:" + this.getAge() + "\t性别:" + this.getGender() + "\t学号:"
				+ this.number + "\t成绩:" + this.avg);
	}
}

Teacher类

package test1;

public class Teacher extends People {
	private String employeeNumber; // 教师号
	private int salary; // 工资
	public static int teacherTotal = 0; // 在构造方法中添加

	public Teacher() {
		teacherTotal++;
	}

	public Teacher(String name, int age, String gender, String employeeNumber, int salary) {
		super(name, age, gender);
		this.employeeNumber = employeeNumber;
		this.salary = salary;
		teacherTotal++;
	}

	public String getNumber() {
		return employeeNumber;
	}

	public void setNumber(String employeeNumber) {
		this.employeeNumber = employeeNumber;
	}

	public int getWages() {
		return salary;
	}

	public void setWages(int salary) {
		this.salary = salary;
	}

	public static int getTeacherTotal() {
		return teacherTotal;
	}

	public static void setTeacherTotal(int teacherTotal) {
		Teacher.teacherTotal = teacherTotal;
	}

	@Override
	public void speech() {
		System.out.println("Teach speech");
	}
}

InterfaceShow接口

package test1;

/**
 * 1.设置接口和抽象方法
 * 
 * @author Administrator
 *
 */
public interface InterfaceShow {
	public void display();
}

Client类

package test1;

public class Client {
	/*
	 * 当student对象时,执行student的speech
	 * 当teacher对象时,执行teacher的speech
	 */
	public static void doSpeech(People people) 
	{
		people.speech();
	}
	/*
	 * 当student对象时,执行InterfaceShow的display
	 * 当teacher对象时,执行InterfaceShow的display
	 */
	public static void doDispaly(InterfaceShow interfaceShow) 
	{
		interfaceShow.display();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student ljw = new Student();
		ljw.setName("林佳雯");
		ljw.setAge(18);
		ljw.setGender("女");
		ljw.setNumber("206550202");
		ljw.setAvg(90);
		
		Student jxj =new Student("金雪佳", 18, "女", "2011111", 90);
		
		ljw.speech();
		jxj.speech(jxj.getName());
		ljw.display();
		//---
		/*
		 * ljw是Student的对象,把Student的对象给People,是向上转换,可以把子类覆盖父类的方法带上去
		 */
		doSpeech(ljw);
		doDispaly(ljw);
		/*
		 * ljw是Student的对象,把Student的对象给InterfaceShow,是向上转换,可以把子类覆盖父类的方法带上去
		 */
		/*
		 * 向上转换的好处是在做上层编程的时候不需要考虑底层细节,顶层以接口的形式出现可以减少错误(因为没写会报错
		 */
	}
}

枚举

enum

可以杜绝人为赋值的错误;枚举值是一个对象,可以调用方法

package app12;
public enum CustomerType { 
    INDIVIDUAL, 
    ORGANIZATION 
}
//这个枚举只有这两种枚举值
//赋值 变量=CustomerType.INDIVIDUAL

INDIVIDUAL, ORGANIZATION 是枚举值 默认静态字段 惯例大写,用逗号隔开。
在内部给enum一个是整数排序值,0表示第一个常量。

package app12;
public class Customer {
    public String customerName;
    public CustomerType customerType; 
    public String address;
}
package ch12.app12;

public class test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Customer c1=new Customer(); //新建一个顾客对象
		c1.customerType=CustomerType.INDIVIDUAL;//顾客状态是散客
	}
}

多重含义

package com.example;

public enum FuelEfficiency {
    EFFICIENT(33, 55),
    ACCEPTABLE(20, 32),
    GAS_GUZZLER(1, 19);
    //如何得到EFFICIENT中的33, 55两个值  
    //min和max分别对应两个值
    //当对象赋值EFFICIENT时会把两个值分别使用构造方法进行放置
    //通过get方法可以分别获得两个值
    
    private int min;
    private int max;
    FuelEfficiency(int min, int max) {
        this.min = min;
        this.max = max;
    }
    public int getMin() {
        return this.min;
    }
    public int getMax() {
        return this.max;
    }
}

package app12;
public class Shape {
    private enum ShapeType { //内部类 定义一个ShapeType的枚举类
        RECTANGLE, TRIANGLE, OVAL
    };
    private ShapeType type = ShapeType.RECTANGLE; 
    //定义一个字段 把RECTANGLE给他赋值
    
    @Override
    public String toString() {
        if (this.type == ShapeType.RECTANGLE) {
            return "Shape is rectangle";
        }
        if (this.type == ShapeType.TRIANGLE) {
            return "Shape is triangle";
        }    
        return "Shape is oval";
    }
}

枚举,在Java5.0以后才有。
为了处理某一样东西的所有类型列举出来。
好处:

  1. 方便记忆
  2. 防止错误输入
  3. 具有多重含义

java.lang.Enum类
定义一个enum的时候,编译器创建了一个类定义,是java.lang.Enum类的直接子类。

具有以下属性:

  • 没有公有的构造函数,使得不可能实例化
  • 隐式地是静态的
  • 每一个enum常量只有一个实例
  • 可以在一个enum上调用values方法,以遍历其枚举值,该方法返回对象的一个数组。
  • 可以在values所返回的对象上调用name和ordinal方法,以分别获取实例的名称和排序值

名称:.name是返回枚举值的字符串
排序值:.ordinal是返回枚举值的排序,排序从0开始

可以用for循环【foreach循环 与下标无关】来遍历enum中的值 首先要调用values方法,返回一个类似数组的对象,其中包含了指定enum的所有值。

CustomerType是枚举类,customerType是对象,是values返回的类似数组的对象

枚举1

package ch12.app12.solft;

public enum Gradee {
	FALSE,PASS,GOOD,EXCELLENT;
	//一个Gradee的枚举类,里面有四个枚举值是FALSE,PASS,GOOD,EXCELLENT
	//后面有语句时,枚举值会有要加分号
	public static void main(String[] arg) {
		System.out.println("所有成绩的种类为:");
		for(Gradee m:Gradee.values())
			System.out.println(m.name());
		//name是返回枚举值的字符串
		
		Student stu=new Student();
		stu.name="zhangsan";
		stu.gradee=Gradee.EXCELLENT;
		stu.displayGradee();
		System.out.println(stu.getClass().getName()); 
		//返回相关Student的全部内容,把name(Student)打印成字符串
		//输出结果是ch12.app12.solft.Student
	}
}
class Student{
	String name;
	Gradee gradee;
	
	public void displayGradee() {
		System.out.println("名字:"+this.name+"成绩:"+this.gradee.name());
	}
}

枚举2

Class类---反射类

从技术上说,由于enum是一个类,一个enum可以有构造方法和方法。如果有构造方法,访问级别必须是私有或者默认的。如果一个enum定义包含了常量以外的其他内容,常量必须在其他内容前面并且以分号结束。

package ch12.app12;

public enum Weekend {
    SATURDAY,
    SUNDAY;
    
    private Weekend() {
    }
    
    @Override
    public String toString() {
        return "Fun day " + (this.ordinal() + 1);
    }
    public static void main(String[] args) {
        // print class name
        System.out.println(Weekend.SATURDAY.getClass().getName());
        	//返回相关Weekend的全部内容,getName()打印成字符串
        	//通过这个可以知道weekend对象是哪个类的
      		//输出结果是ch12.app12.Weekend
        
        for (Weekend w : Weekend.values()) {
            System.out.println(w.name() + ": " + w);
            //System.out.println(w.name() + ": " + w.toString());
            //打印出对象等同于打印出对象toString
        }
    }
}

枚举3

枚举类实现接口

  1. 在程序运行的区域:枚举值.接口方法(也需要进行覆盖)

  2. 在创建枚举值的时候:

    枚举值{
    public void 抽象方法名(){
    内容
    }
    }
    

第一个方法是所有枚举值使用的抽象方法一样。
第二个方法是不同的枚举值用的抽象方法内容不同(每个枚举值都需要覆盖方法)。

posted @ 2022-09-15 14:42  饺子少蘸醋  阅读(36)  评论(0编辑  收藏  举报