//面向对象(基础)
/* 3个主要特性:
一、封装性,面向对象的方法所要遵循的一个汇总昂要原则就是封装性,一是指把对象的属性和行为看成一个密不可分的整体,将两者封装在一个不可分割的 独立单位(即对象)中;另一个含义就是信息的隐藏。把不允许修改的。不想让外界知道的信息隐藏起来。
封装机制在程序设计中表现为:把描述对象属性的变量即实现对象功能的方法何在一起,定义为一个程序单位,并保证外界不能任意修改其内部的属性值,也不能任意调动其内部的功能方法。
封装机制的另一个特点就是可以为封装在一个整体内的变量及方法规定不同等级的可见性和访问权限。
二、继承性
继承是面向对象方法中的主要概念,并且是提高软件开发效率的重要手段。
面向对象程序设计中的继承机制大大增强了程序代码的课复用性。,提高了软件的开发效率,降低了程序产生错误的可能性,也为程序的修改扩充提供了便利。
三多态性
多态是面向对象程序设计的主要特征,多态是允许程序组出现重名现象,Java语言中含有方法重载和对象多态两种形式多态。
方法重载就是在一个类中,允许多个方法使用同一个名字,但是方法的参数不同,完成的功能也不同。
对象多态是子类对象可以与父类对象进行相互转换,而且根据其使用的子类的不同完成的功能也不同。
多态的特性使程序的抽象程度和简介程度更高,有助于程序设计人员对程序的分组协同开发。 */
/*
类的定义
类是有属性和方法组成的,属性中定义类一个个的具体信息,一个属性就是一个变量,而方法是一些操作的行为。在程序设计中,定义类要按照具体的语法要求完成:
class 类名称{
数据类型 属性;
------------- //声明成员变量(属性)
public 返回值的数据类型 方法名称(参数1,参数2,---){
程序语句;
return 表达式; //定义方法的内容
}
}
对象的创建及使用
类名 对象名称 = null; //声明对象
对象名称 = new 类名(); //实例化对象
用以上格式产生对象分为声明对象和实例化对象两步。当然也可以直接一步完成: 类名 对象名称 = new 类名()
对象的创建过程与之前数组的定义格式相似,因为类和数字都属于引用数据类型,只要是引用数据类型的使用格式都可以使用这个定义样式。 */
class person {
String name; //声明姓名属相
int age; //声明年龄属相
public void tell() { //取得信息的方法
System.out.println("姓名:" + name + "年龄:" + age);
}
}
public class ClassDemo02 {
public static void main(String[] args) {
Person per = new Person(); //创建并实例化对象
}
}
/* 以上程序在主方法中实例化了一个Person对象,对象名称为per。
对象的实例化是一套划分堆。栈空间的,所有的对象名称在栈内存
(实际上栈内存中实际保存的是堆内存空间的访问地址),
而对象的具体内容则保存在对于的堆内存之中,必须使用new关键字才能开辟堆内存空间,*/
//访问属性和方法的语法实现:
//访问属性:对象名称.属性名
//访问方法:对象名称.方法名()
package lz;
class Person {
String name;
int age;
public void tell() {
System.out.println("姓名" + name +";年龄:" + age);
}
}
public class ClassDemo01 {
public static void main(String[] args) {
Person per = new Person();
per.name = "张三";
per.age = 30;
per.tell();
}
}
//对象的引用传递
/* 如果一个对象要被使用 则对象必须被实例化,如果没有实例化就直接调用了对象的属性或方法没回直接出现异常:Exception in thread "main" java.lang.NullPointerException.
该异常时开发中最常见的异常 */
package lz;
public class Person {
String name;
int age;
public void tell() {
System.out.println("姓名:"+ name + ",年龄:" + age);
}
}
public class ClassDemo04 {
public static void main(String[] agrs) {
Person per1 = null;//声明对象
Person per2 = null;//声明对象
per1 = new Person();//实例化对象
per2 = new Person();//实例化对象
Person per3 = null;//声明对象
per3 = new Person();//实例化对象
per1.name = "qw";
per1.age = 66;
System.out.println("------------");
per1.tell();
per2.name = "pui";
per2.age = 656;
System.out.println("------------");
per2.tell();
per3.name = "pp";
per3.age = 56;
System.out.println("------------");
per3.tell();
}
}
//封装!
//实际开发中要将类中的属性封装--关键词private
/* //格式: 为属性封装---- private 属性类别 属性名称;
为方法封装:private 方法返回值 方法名称(参数1,参数2——---) */
/* 为了解决属性必须封装且又必须方位的毛段,在Java卡法中对于私有属性的访问必须通过setter和getter方法设置和取得 。另外还有一个原因就在在Java中存在反射机制,在各个程序中,反射机制都会利用setter和getter设置和取得属性内容*/
package lz;
class Person {
private String name; //这里加了封装,后面的程序就无法直接获取
private int age; //这里加了封装,后面的程序就无法直接获取
public void tell() {
System.out.println("姓名:"+ getName() + ",年龄:" + getAge());
}
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
age = a;
}
}
public class EncDemo01 {
public static void main(String[] agrs) {
Person per = new Person();
per.setName("AAW");
per.setAge(66);
per.tell();
}
}
//5,4构造方法
/* 实例化一个类的对象后,如果要为这个对象中的属性赋值,则必须使用setter方法;那么通过构造方法可以在对象实例化时直接把对象的值赋值给属性。在面向对象中构造方法的主要作用及时为类中的属性初始化。
要产生一个类的对象就必须使用以下格式的代码:
类名称 对象名称 = new 类名称()
在程序中只要有“()”就可以调用了方法,
构造方法实际上可以视为一种特殊的方法,它的定义当时和普通方法类似,其语法如下:
---构造方法的定义格式:
class 类名称{
访问权限 类名称(类型1,参数1,类型2 参数2------){
程序语句;
---
---//构造方法没有返回值
}
}
要点:
1,构造方法的名称必须与类名称一致;
2,构造方法的声明不能有任何返回值类型的声明。
3,不能在构造方法中使用return返回一个值
关于访问权限::实际上有三种,default、private、public
声明一个构造方法
*/
class Person {
public Person() { //声明构造方法
System.out.println("一个新的Person对象产生");
}
}
public class ConaDemo1 {
public static void main(String[] args) {
System.out.println("声明对象:Person per = null;");
Person per = null; //声明对象时不调用方法
System.out.println("实例化对象:per = new Person(); ");
per = new Person();//实例化对象时调用构造方法
}
}
package lz;
class Person {
private String name; //这里加了封装,后面的程序就无法直接获取
private int age; //这里加了封装,后面的程序就无法直接获取
public Person(String name,int age) {
this.setName(name);
this.setAge(age);
}
public void tell() {
System.out.println("姓名:"+ getName() + ",年龄:" + getAge());
}
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
if(a > 0) {
age = a;
}
}
}
public class EncDemo01 {
public static void main(String[] agrs) {
Person per = new Person("aaw",69);
per.tell();
}
}
/* 5匿名对象
匿名对象就是没有明确给出名字的对象。一般匿名对象值使用一次,而且匿名对象只在堆内存中开辟空间。而不存在栈内存的使用 */
class Person {
private String name;//声明姓名属相
private int age;//声明年龄属性
public Person(String name,int age) { //定义构造方法
this.setName(name);//为name属性赋值
this.setAge(age);//为age属性赋值
}
public void tell() {
System.out.println("姓名" + getName() +".年龄:" + getAge());
}
public String getName() { //取得姓名
return name;
}
public int getAge() { //取得年龄
return age;
}
public void setName(String n) { //设置姓名
name = n;
}
public void setAge(int a) { //设置年龄
if(a >= 0 && a < 150) { //验证代码
}
}
}
public class NonameDemo01 {
public static void main(String[] args) {
new Person("李正",30).tell();//匿名对象
}
}
/* new Person("李正",30) 这就是一个匿名对象,与之前声明的对象不同,此处每天任何栈内存引用它,所以此对象使用一次之后就等待被垃圾收集机制回收。
匿名对象的作用:匿名对象在实际开发中基本都是作为其他类实例化对象的参数传递。匿名对象实际上就是一个堆内存空间,对象不管是匿名还是非匿名的,都必须在开辟堆内存空间之后才可以使用 */
/*String
String声明一个字符串,String本身就是一个类本类,,是一个比较特殊的类。
实例化String对象
对于String可以采用直接赋值的方式进项操作,如下 */
public class StringDemo01{
public static void main(String[] args){
String name = "lizheng";
System.out.println("姓名:" + name);
}
}
//String类的构造方法: public String(String original)
public class StringDemo02{
public static void main(String[] args){
String name = new String("lizheng");
System.out.println("姓名:" + name);
}
}
/* String 的内容比较
对于基本数据类型可以通过”==“进项内容的比较 */
public class StringDemo03{
public static void main(String[] args){
int x = 21;
int y = 33;
System.out.println("两个数字的比较结果" + (x==y))
}
}
//用”==“比较字符串内容
public class StringDemo04{
public static void main(String[] args){
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2;
System.out.println("str1--str2" + (str1==str2));
System.out.println("str1--str3" + (str1==str3));
System.out.println("str3--str2" + (str3==str2));
}
}
/* 运行结果:
str1--str2-----false
str1--str3----false
str3--str2----true
同样的字符串比较为什么出现不一样的结果,主要原因是”==“是用来进行地址值的比较的,虽然str1.2.3内容相同,但是他们在堆内存的位置是不一样的,所以比较的结果也是不相等的。对于这类问题,我们就需要用equals方法
*/
//用equals方法对String的内容进行比较
public class StringDemo05{
public static void main(String[] args){
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2;
System.out.println("str1 equals str2---" + (str1.equals(str2)));
System.out.println("str1 equals str3---" + (str1.equals(str3)));
System.out.println("str3 equals str2---" + (str3.equals(str2)));
}
}
/* 返回结果为:
str1 equals str2---true
str1 equals str3---true
str3 equals str2---true
*/
* String两种实例化方式的区别
String有两种实例化方式,一种是直接赋值,一种是使用标准的new调用构造方法完成实例化,区别在哪里,该使用哪种?
如果想对以上问题进行解释,则必须明白一个重要概念,即一个字符串就是一个String类的匿名对象,匿名对象就是已经开辟了堆内存空间的并可以直接使用的对象 */
//验证一个字符串就是String类的匿名对象
public class StringDemo06 {
public static void main(String[] args) {
System.out.println("\"hello\" equals \"hello\"---" + ("hello".equals("hello")));
}
}
//结果:"hello" equals "hello"---true
/* 一个字符串是可以调用String类中的方法,也就证明了一个字符串就是一个String类的匿名对象;
所以对于String str1 = ”hello“;
实际上就是把一个在堆中开辟好的堆内存空间的使用权给str1对象,实际上使用这种方式的另外一个好处就是:如果一个字符串被一个名称所引用,则易患在有相同的字符串声明是就不会重新开辟空间。 */
//采用直接复制的方式声明多个String对象,并且内容相同,观察地址比较
public class StringDemo07{
public static void main(String[] args) {
String str1 = "lizheng";
String str2 = "lizheng";
String str3 = "lizheng";
System.out.println("str1==str2--" + (str1 == str2));
System.out.println("str1==str3--" + (str1 == str3));
System.out.println("str3==str2--" + (str3 == str2));
}
}
/* 运行结果:
str1==str2--true
str1==str3--true
str3==str2--true
由此可见三个字符串指向同一个堆内存空间。
对于String的以上操作,在Java中称为共享设计,基本思路:在Java中形成一个对象池,在这个对象池中保存报个对象吗,新实例化的对象如果在池中定义了则不在重复定义,而从池中直接取出继续使用,String就是采用了这样的设计吗,所以内容重复时,会将对象指向已存在的实例空间*/
/* 使用标准的new String() 实例化,则是重新开辟堆内存空间,所以一般不使用这种方法*/