1.如果一个类声明为public,那么该类的名字必须和文件名完全一样
(包括大小写)。且由于类名是标识符,由此决定了文件名也必须符合标识符的规则。
2.如果一个类不是声明为public,那么文件名可以和类名不同,
进而不受标识符规则的约束。
3.一个java源文件中可以同时声明多个类, 编译后每个类会生成独立的字节码文件(.class文
件)。
4.一个java源文件中可以同时声明多个类,但是public的类最多只能一个且该类通常称为主类
(带main方法),文件名和主类一样。如果没有public类,则文件名随便取。
public class Hello1{//主类
public static void main(String args[]){
System.out.println("hello1...."); //int i;
MyDate d = new MyDate();
d.year=2017;
d.aa();
}
}
//public class Hello2{
class Hello2{
public static void main(String args[]){
System.out.println("hello2....");
}
}
class MyDate{
int year;
public void aa(){
System.out.println("year:"+year);
}
}
5.类名{
若干个变量(属性); //成员变量
若干个函数(方法); //成员方法
}
public class Soldier{
String name;
int blood;
int pos;
int attack;
//Cloth cc;
//int defense;
public void move(int i){
pos =pos +i;
}
public void attack( Soldier s ){
s.blood = s.blood-this.attack;
}
public String toString(){
return "name:"+name+", blood:"+blood+", pos:"+pos;
}
}
6.String在Java中比较特殊,既可以当作基本数据类型来用,也可以当作引用(类对象)来
使用。
import java.util.*;
public class StringDemo{
public static void main(String args[]){
//demo1();
//demo2();
//demo3();
demo4();
}
public static void demo4(){
double s=0;//浮点数是近似表示
for(int i=0;i<7;i++){
s = s+0.1;
}
System.out.println(s);
}
public static void demo3(){
String str1 = "abc";
String str2 = str1;//字符串的赋值 不是 引用赋值,不会捆绑
str2="ccc";
System.out.println(str1+","+str2);// abc,ccc
String s1 = "aaa";
String s2 = "aaa";
System.out.println( s1==s2 ); //true
String s3 = new String("aaa");
System.out.println( s1==s3 ); //false
String s4 = new String("aaa");
System.out.println( s3==s4 ); //false
long lg = 10L;
//int x = lg; //WA: 编译错误
float f = lg; //AC: float的精度比long还高
System.out.println( f );
}
/*Scanner中接收字符串的两个方法:
1) sc.next()---以空白符(空格,制表符,换行符)作为分界符
2) sc.nextLine() ---以换行符作为分界符
*/
public static void demo2(){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str = sc.nextLine();//1985/3/20
String[] ss= str.split("/"); //字符串拆分
System.out.println(ss[0]+","+ss[1]+","+ ss[2]);
int year = Integer.parseInt(ss[0]);//把字符串转换成整数
System.out.println(year+10);
}
}
public static void demo1(){
//用法1:基本数据类型 ---直接可以用字符串常量赋值,用"+"号进行连接运算
String str = "Hello World!"; //int i=5;
str="abc123"; //i=10
str = str+"OK"; //i = i+5;
System.out.println(str);
String str2 = "aaabbb";
str2 = str;
System.out.println(str2);
//用法2: 引用类型 (类对象) ---用new的方式创建字符串变量(对象),可以用"变量(对象).方法名(...)"的方式进行调用
String s = new String("abc456");
System.out.println("s: "+s);
int len = s.length();
System.out.println("len: "+ len);
String s2 = s.toUpperCase();
System.out.println("s2:"+s2);
}
}
7.类名(完整名称): 包名+类名
8.基本数据类型赋值,不会捆绑
9.引用赋值必捆绑
package cn.hncu.para1.v1;
//类名(完整名称): 包名+类名
public class MyDateEx {
public static void main(String[] args) {
MyDate d1 = new MyDate(); //类 对象 = new 构造函数();
d1.year = 2017; //对象.成员变量
d1.month = 100;
d1.day = -2;
System.out.println(d1.toString());//2017年10月2日
MyDate d2 = new MyDate();
d2.set(2008, 8, 8);
System.out.println(d2.toString());//2008年8月8日
System.out.println("--------------");
d1.year++;
d2.month++;
System.out.println(d1.toString());//2018年10月2日
System.out.println(d2.toString());//2008年9月8日
MyDate d3 = d2; //引用赋值必捆绑
d3.day++;
System.out.println( d2 ); //d2.toString()
System.out.println( d3 ); //2008年9月9日
d1.setYear(2020);
System.out.println("d1: "+d1); //2020年10月2日
System.out.println("===============");
//拷贝对象
MyDate d4 = new MyDate();
/*
d4.year = d1.year; //基本数据类型赋值,不会捆绑
d4.month = d1.month;
d4.day = d1.day;
*/
d4.set(d1); //替代上面3句,类的封装性
d4.year++;
d1.day++;
System.out.println(d1);//2020年10月3日
System.out.println(d4);//2021年10月2日
}
}
10.myEclipse快捷键:
生成setter-getter方法 : Alt+shift+s --> r
注释: ctrl+/ (行注释,可以取消。//)
ctrl+shift+/ (段注释。 /* -/ )
ctrl+shift+\ (取消段注释)
生成toString方法 : Alt+shift+s --> s
生成构造方法: Alt+shift+s --> o 或 c
11. 类的封装性:
1.所有的变量私有化,写一些setter-getter方法供外面操作这些属性,在这些方法中可以
进行业务控制。
2.写一些构造方法,供外面在创建对象时,直接把数据封装到对象中。
12.构造方法: 名字和类名完全一样,没有返回值(可理解为返回一个对象),用new来调,
调用的结果是在堆内存中创建一个对象空间且返回它的堆内存首地址。
构造方法知识点:
如果我们没有手动写构造方法,则Java会自动帮我们添加一个默认构造方法(空参的构造
方法)。
如果我们手动写了构造方法,则Java不会帮我们添加默认构造方法(空参的构造方法),如
果我们需要就手动再添加。
13.setter-getter方法取名: set+变量名(首字母变大写) , get+变量名(首字母变大写)
package cn.hncu.para1.v2;
/*
* 快捷键:
* 生成setter-getter方法 : Alt+shift+s --> r
* 注释: ctrl+/ (行注释,可以取消。 //)
* ctrl+shift+/ (段注释。 /* -/ )
* ctrl+shift+\ (取消段注释)
* 生成toString方法 : Alt+shift+s --> s
* 生成构造方法: Alt+shift+s --> o 或 c
*
*/
/*
* 类的封装性:
* 1.所有的变量私有化,写一些setter-getter方法供外面操作这些属性,
* 在这些方法中可以进行业务控制。
* 2.写一些构造方法,供外面在创建对象时,直接把数据封装到对象中
*
*/
public class MyDate {
private int year;
private int month;
private int day;
/*
* 构造方法: 名字和类名完全一样,没有返回值(可理解为返回一个对象),
* 用new来调,调用的结果是在堆内存中创建一个对象空间且返回它的堆内存首地址
*
* 构造方法知识点:
* 如果我们没有手动写构造方法,则Java会自动帮我们添加一个默认构造方法(空参的构造方法)。
* 如果我们手动写了构造方法,则Java不会帮我们添加默认构造方法(空参的构造方法),如果我们需要就手动再添加
*/
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public MyDate(){
}
public MyDate(MyDate d){
this.year = d.year;
this.month = d.month;
this.day = d.day;
}
public void setYear0(int y) throws Exception {
if (y < 0 || y > 5000) {
throw new Exception("年份不能为负数或大于5000:" + y);
}
year = y;
}
// setter-getter方法取名: set+变量名(首字母变大写) , get+变量名(首字母变大写)
public void setYear(int year) {
this.year = year;
}
public int getYear() {
return 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;
}
@Override
public String toString() {
return year + "年" + month + "月" + day + "日";
}
}
package cn.hncu.para1.v2;
import java.util.Scanner;
public class MyDateEx {
public static void main(String[] args) {
// demo1();
demo2();
}
private static void demo2() {
MyDate d1 = new MyDate(2017,10,3);
System.out.println(d1);
System.out.println(d1.toString());
MyDate d2 = new MyDate(d1);
d2.setYear(2018);
System.out.println("d1: "+d1);
System.out.println("d2: "+d2);
}
private static void demo1() {
MyDate d1 = new MyDate();
try {
d1.setYear0(201700000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
14.权限从低到高(4种):
private: 只有当前类能够访问
缺省(默认): 只有当前包中的所有类(包含当前类)能访问
protected: 当前包中的类能够访问,其它包中若是子类也能访问。其它包中不是当前类
的子类则不能访问。
public: 任意类(无论是否是相同的包或子类关系)都能访问
15.在构造方法中调用构造方法,用this(...), 且该方法只能在构造方法中调用,功能是给内存
中的数据赋值。
package cn.hncu.para1.v3;
/*
* 权限从低到高(4种):
* private: 只有当前类能够访问
缺省(默认): 只有当前包中的所有类(包含当前类)能访问
protected: 当前包中的类能够访问,其它包中若是子类也能访问。其它包中不是当前类的子类则不能访问。
public: 任意类(无论是否是相同的包或子类关系)都能访问
*/
public class MyDate {
private int year;
private int month;
private int day;
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public MyDate() {
}
public MyDate(MyDate d) {
//在构造方法中调用构造方法,用this(...), 且该方法只能在构造方法中调用,功能是给内存中的数据赋值
this(d.year,d.month,d.year);
}
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;
}
@Override
public String toString() {
return "MyDate [year=" + year + ", month=" + month + ", day=" + day
+ "]";
}
}
public class MyDateEx {
public static void main(String[] args) {
MyDate d = new MyDate();
System.out.println( d instanceof MyDate);
String str= new String("abc123");
System.out.println( str instanceof String );
}
}
小练习
1.编程:写一个矩形类(类名为:Rect),包含:
①两个protected整型属性,分别代表:宽、高;
②两个构造方法:一个带两个参数,一个不带参数;
③两个方法:求面积area()、求周长perimeter()
package cn.hncu.para1.ex;
/*
* //源文件(类)换名: 在左侧导航栏选中文件(类) --> F2 --> 输入新的名字
*
* 97、编程:写一个矩形类(类名为:Rect),包含:
* ①两个protected整型属性,分别代表:宽、高;
* ②两个构造方法:一个带两个参数,一个不带参数;
* ③两个方法:求面积area()、求周长perimeter()
*/
public class Rect {
protected int width;
protected int height;
public Rect(int width, int height){
this.width = width;
this.height = height;
}
public Rect(){
this(0,0);
}
public int area(){
return width*height;
}
public int perimeter(){
return (width+height)*2;
}
}
2.、编程:写一个复数类(类名为:Complex),包含:
①两个protected整型属性,分别代表:实数部分、虚数部分;
②两个构造方法:一个带两个参数,一个不带参数;
③两个方法:求实数加法的complexAdd(Complex a)方法,能把当前复数对象的
实部、虚部组合成a+bi的字符串形式的String、toString( )方法;
④在main( )方法中对该复数类进行如下功能验证:
调用complexAdd( )方法把1+2i 和3+4i 相加产生一个新的复数4+6i,调用toString( )
方法把新复数转换成字符串“4+6i”,然后用System.out.println( )方法输出该字符串。
package cn.hncu.para1.ex;
/*
98、编程:写一个复数类(类名为:Complex),包含:
①两个protected整型属性,分别代表:实数部分、虚数部分;
②两个构造方法:一个带两个参数,一个不带参数;
③两个方法:求实数加法的complexAdd(Complex a)方法,能把当前复数对象的实部、
虚部组合成a+bi的字符串形式的String toString( )方法;
④在main( )方法中对该复数类进行如下功能验证:
调用complexAdd( )方法把1+2i 和3+4i 相加产生一个新的复数4+6i,
调用toString( )方法把新复数转换成字符串“4+6i”,然后用
System.out.println( )方法输出该字符串。
*/
public class Complex {
protected int real;
protected int virtual;
public Complex(int real, int virtual) {
this.real = real;
this.virtual = virtual;
}
public Complex() {
this(0,0);
}
//破坏现场
public void complexAdd( Complex a){
this.real = this.real + a.real;
this.virtual = this.virtual + a.virtual;
}
//保护现场
public Complex complexAdd2(Complex b ){
Complex c = new Complex();
c.real = this.real + b.real;
c.virtual = this.virtual + b.virtual;
return c;
}
public String toString(){
return real + "+"+ virtual + "i";
}
public static void main(String[] args) {
Complex c1 = new Complex(1, 2);
Complex c2 = new Complex(3, 4);
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
c1.complexAdd(c2);
System.out.println("和:"+c1);
Complex d1 = new Complex(1, 2);
Complex d2 = new Complex(3, 4);
Complex d3 = d1.complexAdd2( d2);
System.out.println("d1:"+d1);
System.out.println("d2:"+d2);
System.out.println("d3:"+d3);
}
}
16.静态的东西(成员变量、成员方法)是属于类的(所有对象公用的), 访问方式: 类名.成员名
---推荐方式,对象名.成员名---可以,但不推荐。非静态的东西属性对象的(仅仅是当前对象
所有)。
17.静态块,在第一次使用类模板时调用且只调用一次。如果要在第一次使用类模板时执行某
些代码如给静态变量赋值(通过多行代码)则用静态块。
static{//静态块,在第一次使用类模板时调用且只调用一次。如果要在第一次使用类模板时执行某些代码如给静态变量赋值(通过多行代码)则用静态块。
Calendar c = Calendar.getInstance();
thisYear = c.get( Calendar.YEAR );
}
18.可以在非静态方法中访问静态成员,但该方法是属于每个对象的---如果是专用于对静态
成员进行操作,最好写成静态的方法。静态方法中不能访问非静态成员,如果要访问得通过
对象。
package cn.hncu.para1.v4;
import java.util.Calendar;
import org.junit.Test;
//静态的东西(成员变量、成员方法)是属于类的(所有对象公用的), 访问方式: 类名.成员名---推荐方式, 对象名.成员名---可以,但不推荐
//非静态的东西属性对象的(仅仅是当前对象所有)
public class MyDate {
private int year;//年
private int month;//月
private int day;//日
private static int thisYear;
static{//静态块,在第一次使用类模板时调用且只调用一次。如果要在第一次使用类模板时执行某些代码如给静态变量赋值(通过多行代码)则用静态块。
Calendar c = Calendar.getInstance();
thisYear = c.get( Calendar.YEAR );
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public MyDate() {
this(1970,1,1);
}
public MyDate(MyDate d) {
this(d.year,d.month,d.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 setThisYear(int thisYear){
this.thisYear = thisYear;
}
*/
//专用于对静态成员进行操作的方法,最好写成静态
public static void setThisYear(int thisYear){
MyDate.thisYear = thisYear;
}
public static int getThisYear(){
return thisYear;
}
@Override
public String toString() {
//return year + "年" + month + "月" + day + "日, 今年:"+thisYear;
return year + "年" + month + "月" + day + "日";
}
//静态方法中不能访问非静态成员,如果要访问得通过对象
public static void aa(){
//year = 2020; //WA
MyDate d = new MyDate();
d.year = 2020;
}
//保护现场
public MyDate yestorday(){
MyDate d = new MyDate(this);
d.day--;
if(d.day==0){
d.month--;
if(d.month==0){
d.year--;
d.month=12;
}
d.day= this.daysOfMonth();
}
return d;
}
//原地修改
public void tomorrow(){
this.day++;
if(this.day>daysOfMonth()){
this.day=1;
this.month++;
if(this.month>12){
this.month=1;
this.year++;
}
}
}
public int daysOfMonth(){
switch(this.month){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return 31;
case 4: case 6: case 9: case 11:
return 30;
case 2:
return isLeapYear()? 29: 28;
default:
return 0;
}
}
public boolean isLeapYear(){
boolean boo= isLeapYear(this.year);
return boo;
}
public static boolean isLeapYear( int y){
boolean boo= (y%400==0 || (y%100!=0 && y%4==0) ) ;
return boo;
}
public static void main(String[] args) {
MyDate d1 = new MyDate();
MyDate d2 = new MyDate(2008,8,8);
d2.setDay(23);
//更改静态变量
//MyDate.thisYear=2018;//类名.成员名---推荐方式
//d1.thisYear= 2019; //对象名.成员名---可以,但不推荐
System.out.println(d1);
System.out.println(d2);
MyDate d3 = new MyDate(2010,12,29);
System.out.println(d3);
System.out.println("----------------------");
d3.tomorrow();
d3.tomorrow();
d3.tomorrow();
System.out.println(d3);
MyDate d4 = d3.yestorday();
System.out.println("d4:"+ d4);
}
}
19.浅拷贝: 存在引用赋值--捆绑
public Person( Person p){
this.name = p.name; //基本数据类型,值拷贝
this.birth = p.birth; //☆引用赋值必捆绑 --地址拷贝
}
20.深拷贝: 让所有的变量赋值都达到 基本数据类型赋值的深度
public Person( Person p){
this.name = p.name; //基本数据类型,值拷贝
this.birth = new MyDate(p.birth); //☆引用赋值必捆绑 --地址拷贝
}
package cn.hncu.para1.v4;
public class Person {
private String name;
private MyDate birth;
public Person(String name, MyDate birth) {
this.name = name;
this.birth = birth;
}
//浅拷贝: 存在引用赋值--捆绑
/*
public Person( Person p){
this.name = p.name; //基本数据类型,值拷贝
this.birth = p.birth; //☆引用赋值必捆绑 --地址拷贝
}
*/
//深拷贝: 让所有的变量赋值都达到 基本数据类型赋值的深度
public Person( Person p){
this.name = p.name; //基本数据类型,值拷贝
this.birth = new MyDate(p.birth); //☆引用赋值必捆绑 --地址拷贝
}
public Person() {
this("NoName",new MyDate());
}
@Override
public String toString() {
return name + ", " + birth;
}
public static void main(String[] args) {
MyDate d = new MyDate(1996, 10, 4);
Person p1 = new Person("Jack", d);
System.out.println("p1: "+p1);
System.out.println("-------------");
Person p2 = new Person(p1);
p2.birth.tomorrow();
p2.name="Tom";
System.out.println("p1: "+p1);
System.out.println("p2: "+p2);
}
}