1、继承
public class Test1 {
public static void main(String[] args) {
GoodStudent goodStu = new GoodStudent();
goodStu.age=18;
goodStu.name = "jack";
//String nickName = goodStu.nickName; //无法访问
goodStu.jiangzhuang=5;
goodStu.study();
goodStu.introduce();
goodStu.say();
}
}
class Student{
int age;
String name;
private String nickName="咪咪";
void study() {
System.out.println("我是一个学生,我在学习");
}
void introduce() {
System.out.println("我的名字是"+name+ "我的年龄是:"+age);
}
}
class GoodStudent extends Student{
int jiangzhuang;
void say() {
System.out.println("我有"+jiangzhuang+"张奖状");
}
}
总结:
①私有成员(属性和方法)不能继承
②构造方法不能继承
③如果子类和父类中的属性相同,则子类会覆盖父类中的属性
④如果子类中的方法和父类中的方法签名相同,会重写(override)
方法签名:方法名+方法的参数个数和类型+返回值
2、构造函数Constructor
构造函数的特点:
①和类名相同
②没有返回值,void也不行
③在对象创建的时候执行,同一个对象构造函数只能执行一次
附:对象创建的本质就是执行构造函数
④构造函数可以重载,但不可以重写
⑤如果没有显式的声明构造函数,系统会生成一个默认的无参的构造函数,如果显示的声明了构造函数,系统将不再帮我们生成构造函数
3、对象和内存
public class Test2 {
public static void main(String[] args) {
Dog d1 = new Dog(2,"tom");
Dog d2 = d1;
d2.name="jack";
System.out.println(d1.name); //jack
}
}
class Dog{
int age;
String name;
public Dog(int age, String name) {
this.age = age;
this.name = name;
}
}
匿名对象:
①对象中的属性或方法只访问一次
②做为方法的参数
4、static
public class TestStatic {
public static void main(String[] args) {
Mouse m1 = new Mouse();
Mouse m2 = new Mouse();
Mouse m3 = new Mouse();
Mouse m4 = new Mouse();
System.out.println(m4.count); //1
}
}
class Mouse{
int count;
public Mouse() {
count++;
}
}
可以看到,每次new创建出来的对象,都是新的实体,对实体自身的变量的改变不会影响其他的实体,本例中,如果想让count共享,可以用 static int count; 静态变量,是放在方法区中的,方法区中的数据,被多个类实例共享
public class TestStatic {
public static void main(String[] args) {
Mouse m1 = new Mouse();
Mouse m2 = new Mouse();
Mouse m3 = new Mouse();
Mouse m4 = new Mouse();
System.out.println(m4.count); //4
System.out.println(m1.count); //4
}
}
class Mouse{
static int count;
public Mouse() {
count++;
}
}
5、总结static
(1)static 表示“静态”
(2)用static修饰属性,存放在方法区中,为所有的类实体所共享
(3)静态成员,不依赖对于类对象而存在,可以用类名直接调用
(4)静态属性是在类加载的时候初始化的,而且只会初始化一次
public class Test5 {
public static void main(String[] args) {
Person.speak();
//输出getName
}
}
class Person{
static String name = getName();
static void speak() {
}
static String getName() {
System.out.println("getName");
return "中国";
}
}
(5)在静态上下文 ,不可以访问非静态成员,在非静态上下文中,可以访问静态成员
6、this关键字
this 关键字用来访问本类中的成员,最常用的是在构造函数中给本类中的属性进行初始化
this(参数列表) //在构造方法中,访问本类中的其他构造方法,比如
class Compter{
private String cpu;
private String mainboard;
private int disk;
private int memory;
Compter(String cpu,String mainboard){
this.cpu=cpu;
this.mainboard=mainboard;
}
Compter(String cpu,String mainboard,int disk,int memory){
//在本类的构造方法中,调用本类的其他构造方法
this(cpu,mainboard);
this.disk=disk;
this.memory=memory;
}
void start() {
System.out.println("电脑开机。。滴。。系统自检。。。");
System.out.println("CPU:"+cpu);
System.out.println("主板:"+mainboard);
System.out.println("硬盘大小:"+disk + "T");
System.out.println("内存大小:"+memory + "G");
}
}
注意:
①用this()调用本类中的其他构造方法这个动作,必须在本类的构造方法中进行
②用this()调用本类中的其他构造方法,必须放在第一行,原因:要构造子类,必须先构造父类
7、关于main方法
public static void main(String[] args) {
}
(1)public 表示这个方法是公共的
(2)static 表示这个方法是静态的
(3)void 表示这个方法没有返回值
(4)String[] 表示这个方法接收一个String 数据类型的参数
(5)args 参数名
给main函数传参:
public class TestMain {
public static void main(String[] args) {
System.out.println(args.length);
for(int i=0;i<args.length;i++) {
System.out.println(args[i]);
}
}
}
方法一:使用命令行
javac TestMain.java
java TestMain cat dog fish
方法二:使用集成开发环境,以eclipse为例
Run As =>>Run Configuration >> Arguments >> Program Argumetns 在下面的框里添上就可以,多个用空格分开
8、代码块
构造代码块,在类对象创建的时候执行,早于构造函数,每个类对象创建都会执行构造代码块
静态代码块,在类加载的时候执行,而且只执行一次
public class Test7 {
public static void main(String [] args) {
new User();
new User();
/*
* 输出为:
* 静态代码块
构造代码块
构造方法
构造代码块
构造方法
*/
}
}
class User{
User(){
System.out.println("构造方法");
}
{
System.out.println("构造代码块");
}
static {
System.out.println("静态代码块");
}
}
静态代码块和静态属性的初始化是同级的,谁在前面先初始化谁
public class Test7 {
public static void main(String [] args) {
new User();
/*
* 输出为:
* getAge
* 静态代码块
*/
}
}
class User{
static int age = getAge();
static {
System.out.println("静态代码块");
}
static int getAge() {
System.out.println("getAge");
return 18;
}
}
构造代码块和普通成员的级别是一样的,谁在前先初始化谁
public class Test7 {
public static void main(String [] args) {
new User();
/*
* 输出为:
* 构造代码块
* getAge
*/
}
}
class User{
{
System.out.println("构造代码块");
}
int age = getAge();
int getAge() {
System.out.println("getAge");
return 18;
}
}
9、递归算法
public class Test8 {
public static void main(String [] args) {
a();
}
static void a() {
System.out.println("a调用了"); //达到一定次数时报java.lang.StackOverflowError
a();
}
}
如果想知道递归多少次时栈内存溢出,可以使用下面的程序
public class Test8 {
static int count;
public static void main(String [] args) {
a();
}
static void a() {
System.out.println("a调用了第"+count+"次"); //达到一定次数时报java.lang.StackOverflowError
count++;
a();
}
}
因此递归必须要有一个结束条件,要不然会造成死递归,内存溢出
递归算法的一般步骤:
①明确函数要做什么
②确定递归的结束条件
③找到函数的等价关系式,缩小范围,进行递归调用
示例一:求某一个数的阶乘
public class Test9 {
public static void main(String [] args) {
int x = jiecheng(6);
System.out.println(x); //720
}
static int jiecheng(int n) {
if(n==1)return 1;
else return jiecheng(n-1)*n;
}
}
示例二:求斐波那契数列的某一项的值
public class Test9 {
public static void main(String [] args) {
int x = f(20);
System.out.println(x); //6765
}
static int f(int n) {
if(n==1)return 1;
else if(n==2)return 1;
else return f(n-1)+f(n-2);
}
}