目录
一、控制流程语句
二、数组
1、声明数组方式
2、数组初始化
3、for-each循环语句
三、类和对象
1、类
2、对象
3、构造函数
4、static关键字
5、包
四、继承
1、继承的使用
2、子类对象的创建
3、方法的覆写
4、多态和动态绑定
5、抽象类
五、接口和内部类
1、接口
2、内部类
六、面向对象的编程
1、封装
2、合理使用类
七、异常处理
八、线程
1、Thread创建线程
2、Runable创建线程
3、线程周期
4、一个典型的应用场景
跳转语句
break:跳出循环
continue:在循环中,跳出单次循环
return:
int i[];
int []i;
以上方式只是声明数组,并没有对其分配内存,所以不能存放或访问它的元素。可以用new对数组分配内存空间:
int i = new int[5];
这样就可以访问了,int j=i[0];
//创建一个int型数组
int[] array1 =new int[3];
//对数组元素赋值
array1[0]=1;
array1[1]=2;
array1[2]=3;
//另一种数组创建方式
int[] array2={1,2,3};
object是一个特殊的类,是所有类的父类,表示所有的对象。当一个数组含有多种数据类型的时候,object可以存所有数据类型的数据。
for(int i=0;i
(1)类实际上是定义一个模板,而对象是由这些模板产生的一个实例。
public class Human {
//声明各类变量来描述类的属性
private String name;
private String sex;
private int age;
public void work(){
System.out.println("我在工作");
}
public void eat(){
System.out.println("我在吃饭");
}
public String getName() {
return name;
}
public void setName(String name){
this.name=name;//this就代表该类,可以调用所有公有、私有变量以及所有的方法。
}
public String getSex(){
return sex;
}
public void setSex(String sex){
this.sex=sex;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
}
(2)带参数和返回值的方法(详解一个类的结构)
public class Tools {//一个类,class是类的标志,Tools是一个类的名字
public float plus(float a,float b) {//类中的方法,“方法”就类似C中的“函数”
//public代表该方法可以被所有的类访问,float代表返回值的类型,puls代表方法的名字
float c = a+b;
return c;
}
}
//在一个新类中调用上述plus方法详解
public class TestTools {
public static void main(String[] args) {
Tools tools = new Tools();//以Tools类为模板创建一个名为tools的对象;new是创建对象的标识,最开始的Tools就相当于C语言中的return给主函数的数据类型,现在new完,就是给主函数返回一个Tools类型的变量。
float f = tools.plus(2.1f, 3.2f); ,
System.out. println(f);
}
}
(3)方法的重载
定义:在Java中,支持多个同名的方法,只要它们的参数个数或类型不一样就可以,这种情况就叫方法的重载。
!!!这里说的参数个数和类型指的是传入的参数个数与类型。
Human zhangsan =new Human();
zhangsan就是类Human的一个对象,它可以使用Human里面的所有公用的方法。
创建对象使用的语句如下:
Human zhangsan =new Human();
实际上是调用了一个方法,不过这个方法是系统自带的方法,由中于这个方法被用来构造对象,所以把它称为构造函数。构造函数的作用是生成对象,并对对象的实例变量进行初始化。构造函数有一个很明显的特点是它的名字必须跟类名相同,并且没有返回值类型。
静态变量、静态方法都是属于类的,可以直接用“类名.变量名或“类名.方法名”的方式来访问。而普通的变量方法的访问都需要先new一个对象的方式才可以。
静态常量用来表示一些不会变的信息,它的值不允许改变。例:
public class StaticDemo {
public static final float PI=3.14F; //静态常量,final表示不变
public static int i=1; //静态变量
//静态方法
public static float yuanmianji(float r) {
return PI*r*r;
}
//普通方法
public float zhouchang(float r) {
return 2*PI*r;
}
public static void main(String[] args) {
System. out . println(StaticDemo. i);//1
System . out . print1n(StaticDemo . yuanmianji(1));//3.14
StaticDemo s = new StaticDemo( );
System. out. println(s. zhouchang(1));//6.28
System. out . print1n(s .yuanmianji(1));//3.14
}
}
包实际上就是一个个的文件夹,调用不同包的类时,需要将包引入才可以。关键词:package。
调用某个包内的一个类:import package.具体的类;
调用某个包内的全部类:import package.*
继承是面向对象编程的重要特征之一。继承就是在现有类的基础,上构建新类以满足新的要求。在继承过程中,新的类继承原来的方法和实例变量,并且能添加自己的方法和实例变量。
继承是指声明一些类,可以进一步声明这些类的子类,子类具有父类已经拥有的一些方法和属性,子类也称派生类。
继承是在已有类的基础上构建新的类。已有的类称为超类、父类或基类,产生的新类称为子类或派生类。
//定义了一个Animal的父类
public class Animal {
String name;
int age;
public void eat() {
System.out.print1n( "动物吃饭");
}
}
//定义了一个鸟类,继承于Animal
public class Bird extends Animal{//extends是继承的关键字,Bird是Animal的子类,Animal是Bird的父类
String wing;
void fly() {
System.out.print1n("鸟会飞");
}
public void eat() {//定义新方法
System.out.println("鸟在吃食");
}
public class TestBird {
public static void main(String[ ] args) {
Bird bird = new Bird();//创建了一个bird的对象,基于Bird类
bird.fly();//调用Bird类的fly方法
bird.age = 2;//调用Bird父类的方法
bird.eat();//调用的是Bird这个子类中的方法,也就是说先调用Bird类中的方法,再寻找是否Bird父类中有eat这个方法。其实也就是方法的复写
}
}
java中不支持多继承,一个类的直接父类只能有一个。它想要继承多个类的话,怎么办呢?只能通过接口的概念。
子类对象的创建过程是怎么样的呢?从最顶层的基类开始往下一层层的调用默认构造函数。
class A{
A(){
System.out.print1n("调用A的构造函数"); .
}
A(int i){
System.out.print1n("调用A的有参构造函数") ;
}
}
//类B继承A
class B extends A{
B(){
(1/2)super(1);//调用父类中特定的方法
System.out.println("调用B的构造函数" );
}
}
public class CallConstructor {
public static void main(String[] args) {
B b=new B();
}
}
//运行结果:
(1)调用A的构造函数 (2)调用A的有参构造函数
调用B的构造函数
覆写(override)是指可以重新写一个和父类中方法名参数都一样的方法,在子类中调用该方法时将会调用子类里重写的这个方法,要想再调用父类中的方法只能用super关键字才可以。
覆写(override) 和重载( overload)相同的地方是方法名都是一样的。区别是覆写是重新写父类中的方法,重载是一个类里面的方法参数不一样。覆写举例:
class Parent{
void method() {
System.out.print1n("父类中的方法");
}
}
class Child extends Parent{
void method() {
super.method();//调用父类中的method方法
System.out.println( "子类中的方法");
}
}
public class OverrideDemo {
public static void main(String[ ] args) {
Child child = new Child( );
child.method();
}
}
多态是指同一个方法根据上下文使用不同的定义的能力。从这一点上看,前面讲的方法覆写和方法重载都可被看作是多态。但是Java的多态更多的是跟动态绑定放在一起理解的。
动态绑定是一种机制,通过这种机制,对一个已经被重写的方法的调用将会发生在运行时,而不是在编译时解析。举例:
class P{
void method() {
System.out.print1n("父类中的method");
}
class C extends P{
void method() {
System.out.print1n("子类中的method");
}
void method1() {
System.out.println("子类中的method1");
}
public class DuotaiDemo {
public static void main(String[] args) {
P c=new C();//C是父类P中的结构
C.method();//java在运行的时候,会去找子类中的method方法,但是c.method1()不会编译成功,因为父类P中没有method1()方法。
((C)c).method1();//将P类型的c类,强制转换为C类
}
}
//运行结果
子类中的method
子类中的method1
抽象类是指在类中定义方法,但是并不去实现它,而是在它的子类中去具体的实现。定义的抽象方法不过是一个方法占位符。继承抽象类的子类必须实现父类的抽象方法,除非子类也被定义成一个抽象类。
(1)抽象类的定义
定义抽象类是通过abstract关键字实现的。在抽象类中的方法不一定是抽象方法,但是含有抽象方法的类必须被定义成抽象类。
//定义一个Animal的抽象类
public abstract class Animal {
String name;
int age;
public abstract void eat( );|
}
public class Bird extends Animal{
String wing;
void fly() {
System.out.println("鸟会飞");
}
@Override//重写抽象类里的eat方法
public void eat() {
// TODO Auto-generated method stub
System.out.println("鸟在吃食");
}
}
(2)抽象类的使用
抽象类不可以实例化,也就是不可以使用new命令,例如:
Animal animal=new Animal();
但是可以创建抽象类的对象变量,只是这个变量只能用来指向它的非抽象子类的对象,注意该抽象类变量不可以调用抽象类中没有的方法。例如:
Animal animal=new Bird();//Bird为Animal的子类,该animal又只能用Animal类中已经定义的方法。
(3)Object类
Object类是所有类的祖先类。在Java中如果定义了一个类并没有继承任何类,那么它默认继承Object类。而如果它继承了一个类,则它的父类,甚至父类的父类必然是继承自Object类,所以说任何类都Object类的子类。
Object类可以存放任何数据类型。
接口定义了一系列的抽象方法和常量,形成一个属性集合。接口定义完后,任何类都可以实现这个接口,而且一个类可以实现多个接口。实现接口的类必须实现接口中定义的抽象方法,具体细节由类自己定义。
(1)接口的定义
接口的关键字是interface,类的关键字是class。例如:
public interface Animal {
//接口中的常量
public static final int CHANGLIANG = 1;
//接口中的方法
public void eat();//抽象的方法
public String getName();//抽象的方法
}
(2)接口的定义
接口的实现是指具体实现接口的类。接口的声明仅仅给出了抽象的方法,相当于实现定义了程序的框架。实现接口的类必须要实现接口中定义的方法,除非这个类是抽象类。例如:
public interface Animal {
//接口中的常量
public static final int CHANGLIANG = 1;
//接口中的方法
public void eat();//抽象的方法
public String getName();//抽象的方法
}
public class Tiger implements Animal{
//实现接口中定义的方法
public void eat() {
System.out.println("老虎吃肉");
}
public String getName() {
return "老虎";
}
public static void main(String[] args) {
Animal tiger = new Tiger();//多态
tiger.eat();
System.out.print1n(tiger.getName());
}
}
接口之间也可以有继承关系。继承接口的接口拥有它的父接口的方法,它还可以定义自己的方法。例如:
public interface Animal {
//接口中的常量
public static final int CHANGLIANG = 1;
//接口中的方法
public void eat();//抽象的方法
public String getName();//抽象的方法
}
public interface Mammal extends Animal{
void run();
}
//要实现Mammal,必须实现两个接口中的所有方法。
(3)抽象和接口的比较
1)一个类可以实现多个接口,但只能继承-一个抽象类。
2)抽象类可以有非抽象方法,接口中定义的方法必须全部为抽象方法。
3)在抽象类中定义的方法,可以是public、protected、 private或默认值,但在接口中全是public的。
4)抽象类可以有构造函数,接口不能。两者都不能实例都能通过它们来存放子类对象。
内部类定义在其它类的内部,内部类所在的类被称为宿主类。内部类种类很多,有静态内部类、非静态内部类、定义在方法内的局部内部类,还有连名字都没有的匿名内部类。例如:
public class Outer {
String outString = "宿主类的变量";
void useInner() {
Inner inner = new Inner( );
inner.print();
}
/**内部类*/
class Inner{
void print() {
System.out.println("内部类输出语句");
System.out.println(outString);
}
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.useInner();
}
}
//输出结果:
内部类输出语句
宿主类的变量
//成员变量的封装
public class Human {
private String name; / /变量声明成私有的
private String sex;
public String getName() { / /用方法来访问私有变量
return name ;
}
public void setName(String name) {
this.name = name ;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
//成员变量的继承(一般继承方法)
public class Parent {
public String pString ="父类的public属性";
}
public class Children extends Parent{
public void print() {
System.out.print1n(pString);
public static void main(String[] args) {
Children child = new Children();
child.print(); .
}
}
成员变量的覆盖
父类和子类中同样声明一个变量,子类访问该变量时是访问子类的变量,要想访问父类的,要使用super关键字。例如:
public class Parent {
public String pString ="父类的public属性";
}
public class Children extends Parent{
public String pString = "子类中的字符串";
public void print() {
System.out.println(super.pString);
}
public static void main(String[] args) {
Children child = new Children();
child.print();
}
}
需要注意以下三点:
(1)合理的分解类
例如:JaveEE中常用的MVC模式:
M:model,具体工作的那一层;
V:View,用户端看到的那一层;
C:contoral,控制层。
public class Controller{
public String control(){
Model model= new Model();
String sth = model.business();
return "view.jsp";
}
}
public class Model{
public String business(){
String s= "在业务层做了一些事";
return s;
}
(2)让类的名字和方法反映它的应用
类的名字、方法名、变量名都尽量反映它表示的东西。方法应该尽量用动词或动词与名词的组合来表示。
(3)复用现有的类
String是个类。
由于硬件问题、资源耗尽、输入错误以及程序代码编写不严谨会导致程序运行时产生异常,这些异常会导致程序终端而不能正常继续运行,所以需要对异常的情况进行妥善处理。例如:
public class TryCatchDemo {
public static void main(String[] args) {
String str = null;
int strLength = 0;
try {
strLength = str.1ength();
} catch (NullPointerException e) {
e.printStackTrace( );//打印错误信息
}finally {//finally一定会执行。
System.out.print1n("必然执行");
}
System.out.print1n(strlenth);
}
}
pub11C class thorwsDemo{
public static void method() throws NullPointerException{//method中不处理异常
String str = nu1l;
int strLength = str.length();
System. out . print1n(strLength);
}
public static void main(String[] args) {
try{
method();
}catch(NullPointerException e) {
e.printStackTrace();
}
System.out.print1n( "程序结束");
}
}
线程是程序运行的基本单位,一个程序中可以同时运行多个线程。
public class ThreadDemo1 extends Thread {//继承方法
private String name ;
public ThreadDemo1(String name) {
this.name = name;
}
public void run() {
for(inti=0;i<100;i++){
System.out.println(name );
}
}
public static void main(String[] args) {
ThreadDemo1 td1 = new ThreadDemo1("第一个线程");
ThreadDemo1 td2 = new ThreadDemo1("第二个线程");
ThreadDemo1 td3 = new ThreadDemo1("第三个线程");
td1.start();//运行run中的内容,不是.run,而是.start
td2.start();//thread的一个特点!!
td3.start();
}
}
!!!并不一定先调用td1,线程并行。
public class ThreadDemo2 implements Runnable{//实现接口
private String name;
public ThreadDemo2(String name) {
this.name = name ;
}
public void run() {
for(int i=0;i<100;i++) {
System.out.print1n(name);
}
}
public static void main(String[] args) {
Runnable rb1 = new ThreadDemo2("第一个线程");
Runnable rb2 = new ThreadDemo2("第二个线程");
Thread td1 = new Thread(rb1);
Thread td2 = new Thread(rb2);
td1.start();
td2.start();
}
}
四个状态:创建状态、可运行状态、不可运行状态、退出状态。
(1)创建状态
调用new方法产生一个线程对象后、调用start方法前所处的状态。线程对象虽然已经创建,但还没有调用start方法启动,因此无法执行。这个状态可以通过调用start方法进入启动状态,也可以调用stop方法进入停止状态。
(2)可运行状态
当线程对象执行start方法后,线程就转到可运行状态,进入此状态只是说明线程对象具有了可以运行的条件,但线程并不一定处于运行状态。因为可能会有很多线程同时处于可运行状态,而处理器有限,系统通过调度机制实现宏观意义上的运行线程共享处理器。一个线程是否在运行,除了线程必须处于Runnable状态之外,还取决于优先级和调度。
(3)不可运行状态
线程处于不可运行状态是由于线程被挂起或者发生阻塞,例如对一个线程 调用wait()函数后,它就可能进入阻塞状态;调用线程的resume、notify或notifyAll方 法后它才能再次回到可执行状态。
(4)退出状态
一个线程可以从任何一个状态中调用stop方法进入退出状态。线程一旦进入退出状态就不存在了,不能再返回到其他的状态。除此之外,如果线程执行完run方法,也会自动进入退出状态。
public class ThreadDemo3 {
public static void main(String[] args) {
new Thread() {
public voiJId run() {
int i=5;
while(i>0){
System.out.println("i=" + i);
try {
Thread.sleep(1000);//ms为单位
}catch (InterruptedException e) {
e.printStackTrace();
}
i--;
}
System.out.println( "线程执行完了");
}
}. start();
System.out.print1n("线程外");
}
}